【问题标题】:Optimizing for loop in big data frame优化大数据帧中的循环
【发布时间】:2015-02-17 14:35:39
【问题描述】:

我有一个大型数据框(600 万行),其中一行用于进入时间,下一行用于同一单元 (id) 的退出时间。我需要把它们放在一起。

原始数据如下所示(请记住,某些“id”可能会像 id=1 一样进入和退出两次):

df <- read.table(header=T, text='id   time
1  "15/12/2014 06:30"
1   "15/12/2014 06:31"
1 "15/12/2014 06:34"
1 "15/12/2014 06:35"
2  "15/12/2014 06:36"
2  "15/12/2014 06:37"
3 "15/12/2014 06:38"
3 "15/12/2014 06:39"')

我需要的输出:

id  entry   exit
1   15/12/2014 06:30    15/12/2014 06:31
2   15/12/2014 06:34    15/12/2014 06:35
3   15/12/2014 06:36    15/12/2014 06:37
4   15/12/2014 06:38    15/12/2014 06:39

现在我尝试了一个 for 循环,它从第 1 行中选择 id 和进入时间,从第 2 行中选择退出时间,并将它们放在一起:

for (i in 1:nrow(df)){
outputdf[i,1] <- df[i+i-1,1]
outputdf[i,2] <- df[i+i-1,2]
outputdf[i,3] <- df[i+i-1+1,2]
}

问题在于它的效率非常低(适用于 10k 个子集,但不适用于我的 600 万个数据框)。我需要至少花不到一分钟的时间。我在df 中有 600 万行。你知道比这个循环更快的匹配行吗?

【问题讨论】:

标签: r for-loop optimization bigdata


【解决方案1】:

你可以试试

  library(data.table)
  dcast.data.table(setDT(df)[ ,c('.id', 'Seq'):= 
        list(c('entry', 'exit'), gl(.N,2, .N))], id+Seq~.id, value.var='time')

  #   id Seq            entry             exit
  #1:  1   1 15/12/2014 06:30 15/12/2014 06:31
  #2:  1   2 15/12/2014 06:34 15/12/2014 06:35
  #3:  2   3 15/12/2014 06:36 15/12/2014 06:37
  #4:  3   4 15/12/2014 06:38 15/12/2014 06:39

数据

 df <- structure(list(id = c(1L, 1L, 1L, 1L, 2L, 2L, 3L, 3L), time = 
   structure(1:8, .Label = c("15/12/2014 06:30", 
 "15/12/2014 06:31", "15/12/2014 06:34", "15/12/2014 06:35", "15/12/2014 06:36", 
 "15/12/2014 06:37", "15/12/2014 06:38", "15/12/2014 06:39"), class
   = "factor")),.Names = c("id", "time"), class = "data.frame", row.names
  = c(NA, -8L))

【讨论】:

  • 感谢@akrun 的回答,我认为我错过了问题中的一个重要点,即某些“id”可能已经进入和退出两次,所以进入、退出、进入、退出。因此,我将在原始 df 中有 4 行具有相同的 id 号。如果我进行 dcast,我最终会得到每个 id 的 4 条记录,但我需要为每个入口-出口对提供一条记录。作为一个类比,想想航空乘客。通常您可以在目的地机场办理登机手续和退房手续,但也有部分旅客可能在目的地办理登机手续、办理退房手续并在同一天搭乘另一班航班。每个航班我都需要一行。
  • 数据集有一行用于旅客进入,另一行用于旅客出口。有的乘客(大部分)一天要出行好几次,所以进入网络,退出网络,稍后再进入和退出。每个乘客都有一个 ID,但同时也有许多乘客旅行。抱歉,如果听起来很乱
  • 有一个后续问题,因为我需要移动更多列,我有点想用你的代码把它弄下来。 stackoverflow.com/questions/27564299/…
  • @user3507584 我会检查那个。
【解决方案2】:

也许我错过了什么,但是这个怎么样??

indx   <- seq(1,nrow(df)-1,2)
result <- with(df,data.frame(seq=seq(indx),id=id[indx],entry=time[indx],exit=time[indx+1]))
result
#   seq id            entry             exit
# 1   1  1 15/12/2014 06:30 15/12/2014 06:31
# 2   2  1 15/12/2014 06:34 15/12/2014 06:35
# 3   3  2 15/12/2014 06:36 15/12/2014 06:37
# 4   4  3 15/12/2014 06:38 15/12/2014 06:39

【讨论】:

  • 我正在尝试这个解决方案,但我得到了Error in id[indx] : object of type 'closure' is not subsettable。我也得到了time[indx]。你知道为什么吗?
  • 您的数据是否在名为df 的数据框中,df 是否有列timeid
猜你喜欢
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 1970-01-01
  • 2013-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多