2016-08-02 2 views
2

Пусть даны dataframe с двумя колоннами:Производительность Проблемы при работе между двумя столбцами dataframe

  • длиной (длина элементов)
  • findLengthOf (Это строка значений) Индекс элементов для который необходим для длины

Таким образом, необходимо найти всю длину всех индексов во втором столбце и поместить результат в третий столбец. Пожалуйста, смотрите выше примера, где мы ищем длину 1637 и получить 1835:

> df$length[1637] 
[1] 1835 


head(df) 
    length findLengthOf 
1 6434 1637,386.... 
2 4272 4322,414.... 
3 7338 2052,639.... 
4 4932 190,1567.... 
5 2397 8963,844.... 
6 4405 103,4346.... 

    head(df) 
    length findLengthOf   result 
1 6434 1637,386.... 1835, 2404, 4689 
2 4272 4322,414.... 1184, 2721, 7215 
3 7338 2052,639.... 5253, 2998, 6153 
4 4932 190,1567.... 2931, 6496, 7784 
5 2397 8963,844.... 3796, 3488, 6555 
6 4405 103,4346.... 1662, 5481, 1244 

set.seed(123) 
df <- data.frame(length = sample(1e4), 
       findLengthOf = I(replicate(1e4, paste(sample(1:10000,1),sample(1:10000,1),sample(1:10000,1),sep=","), simplify = FALSE))) 

df$result=lapply(lapply(df$findLengthOf,strsplit,split=","), function(x){df[x[[1]],"length"]}) 

код работает, но требуется, чтобы долго. Как я могу улучшить скорость? Также почему

head(lapply(df$findLengthOf,strsplit,split=",")) 

всегда возвращает этот странный список списков с:

[[1]] 
[[1]][[1]] 
[1] "7744" "1346" "4626" 

Есть ли способ, чтобы избежать этих двойных скобок? Любой ответ приветствуется!

Предложение от Давида (набор фиксированных = Т):

> ptm <- proc.time() 
> df$result=lapply(lapply(df$findLengthOf,strsplit,split=",",fixed=T), function(x){df[x[[1]],"length"]}) 
> proc.time() - ptm 
    user system elapsed 
17.220 0.000 17.147 
> ptm <- proc.time() 
> df$result=lapply(lapply(df$findLengthOf,strsplit,split=","), function(x){df[x[[1]],"length"]}) 
> proc.time() - ptm 
    user system elapsed 
17.260 0.000 17.142 
+0

Непонятная 'длина 1637 и получить 1835'? – zx8754

+0

Привет, zx8754, хорошо. Это означает, что df $ length [1637] приводит к 1835 году. Ill update my post. –

+1

Просто добавив 'fixed = TRUE' к вызову' strsplit', вы можете заставить его работать быстрее на ~ X10 раз. Также. оба 'strsplit' и' lapply' возвращают список, следовательно список списков. Мне также интересно, как этот вопрос относится к вашему предыдущему, когда вы проигнорировали сравнение производительности и альтернативные предложения, такие как не соединять строку в первую очередь и т. Д. –

ответ

1

Вот полностью vectotorized решение, но, возможно, память дорого. Я не проверял на производительность

library(data.table) 
res <- matrix(df$length[unlist(setDT(df)[, 
       tstrsplit(findLengthOf, ",", fixed = TRUE, type.convert = TRUE)])], 
       nrow = nrow(df)) 
df$result <- as.list(as.data.frame(t(res))) 
+0

Я ценю усилия, чтобы проверить производительность позже, потому что это время обеда здесь, в Германии. Я опубликую результаты позже. –

+0

Удивительно! Требуется: истекшая пользовательская система 0.04 0.00 0.04 Где я могу узнать больше о веторизации моего кода? У вас есть хорошие учебники? –

+1

Векторный код в R является мышлением. Он поставляется с опытом. Я попытался предоставить несколько интро [здесь] (http://stackoverflow.com/documentation/r/3327/r-code-vectorization-best-practices#t=201608021213337797116). Это также хорошее введение http://www.noamross.net/blog/2014/4/16/vectorization-in-r--why.html –

Смежные вопросы