【问题标题】:Most efficient way for looping over 1.5k rows and updating a dataframe [duplicate]循环超过 1.5k 行并更新数据帧的最有效方法 [重复]
【发布时间】:2014-09-09 19:52:15
【问题描述】:

我从 1.5kk 行的数据框 f 开始,并尝试基于该 f 数据框更新 nxn 数据框 Channels。到目前为止,我有 2 个 for-loops 导致脚本运行非常缓慢。

我有一个表格,其中包含他们最喜欢的用户 ID 和频道(您可以将其视为他们最喜欢的歌曲类型),如下所示:

id_user | id_channel
--------------------
   1    |     43
   1    |     61
   1    |    101
   2    |     43
   2    |    631
  ..    |     ..

我期望得到的是一个数据框Channels,其列和行如下所示:

              id channel
     |  43    61    101   631
---------------------------------
43   |  NA     6     31     9
61   |   3    NA     11     1
101  |   2     1     NA    23
631  |  10     2      3    NA

我在 x 轴和 y 轴上都有 id_channel。这意味着有 6 个喜欢频道 43 的用户也喜欢频道 61,有 1 个喜欢频道 101 的用户也喜欢频道 61,依此类推。

我所做的是在下面的代码中。它可以工作,但由于我的原始表有 1.5kk 行,因此代码需要大约 25 小时才能结束。我认为可能有一种更有效的方法来做到这一点。 f 是具有 1.5kk 行(作为数据帧)的原始数据,lst_users(长度 650k 行)和 lst_channel(长度 50 行)是具有不同 id_usersid_channels 的向量。

基本上,我通过id_user 对原始表进行子集化,然后为每个表循环遍历其喜欢的频道,更新数据帧Channels

for (user in lst_users) {
  sub <- f[f$id_user == user,]

  for (j in 1:nrow(sub)) {
    rindex <- which(lst_channels == sub$id_channel[j])
    cindex <- which(lst_channels == unique(sub$id_channel[-j]))

    Channels[rindex, cindex] <- Channels[rindex, cindex] + 1
  }

}

Channels 数据帧的初始化如下所示(对角线为 NA,矩阵其余部分为 0):

Channels <- diag(NA, nrow= length(lst_channels), ncol= length(lst_channels))

我正在尝试使用apply、mapply、sapply 等函数提出一个解决方案,但无法提供真正有效的解决方案。关于如何解决这个问题的任何想法?

编辑:

正如@alexis_laz 指出的this question 中存在类似的问题,其解决方案可以在此处实现。

解决方案:crossprod(table(f))

【问题讨论】:

  • 太棒了,感谢您的指出。稍后我将发布它与当前实现相比的表现。
  • @alexis_laz,绝对是一个重复的问题,您的链接为邻接表问题提供了完美的答案。

标签: r performance dataframe processing-efficiency


【解决方案1】:

对解决方案 Channels &lt;- crossprod(table(f)) 进行基准测试得出以下结果:

Unit: seconds
                           expr      min       lq  median       uq      max neval
 crossprod(table(f[, c(1, 3)])) 6.059346 6.219557 6.31133 6.471866 7.358821    50

比使用 2 个 for-loops 花费 25 小时 + 的时间快得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-22
    • 2022-07-06
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 2011-12-11
    • 2020-06-09
    • 2017-03-21
    相关资源
    最近更新 更多