【发布时间】: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_users 和 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
}
}
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