循环超过1.5k行并更新数据帧的最有效方法

时间:2014-09-09 19:52:16

标签: r performance dataframe processing-efficiency

我从1.5kk行的数据帧f开始,并尝试根据Channels数据帧更新nxn数据帧f。到目前为止,我有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_users和{的向量{1}}。

基本上,我按id_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 } } 数据帧初始化如下(对角线为NA,矩阵其余部分为0):

Channels

我试图使用诸如apply,mapply,sapply等函数来提出解决方案,但无法实现真正​​有用的功能。关于如何解决这个问题的任何想法?

修改

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

解决方案:Channels <- diag(NA, nrow= length(lst_channels), ncol= length(lst_channels))

1 个答案:

答案 0 :(得分:0)

对解决方案Channels <- 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小时+。