【问题标题】:Optimizing Speed for Populating a Matrix优化填充矩阵的速度
【发布时间】:2016-05-01 16:33:17
【问题描述】:

我正在尝试在 R 中填充一个最终将是对称的大矩阵(55920484 个元素)(因此我实际上只对矩阵的一半执行计算)。结果值矩阵是具有相同行名和列名的方阵。矩阵中的每个值都是比较唯一列表和计算交叉点数的结果。该数据来自更大的数据帧 (427.5 Mb)。这是迄今为止我最快的解决方案,我正在尝试摆脱我知道很慢的循环:

for(i in 1:length(rownames(values))){
  for(j in i:length(colnames(values))){
    A = data[data$Stock==rownames(values)[i],"Fund"]
    B = data[data$Stock==colnames(values)[j],"Fund"]
    values[i, j] = length(intersect(A, B))
  }
}

我尝试了其他几种方法,例如使用带有 SQL 连接的数据库、使用带有 0 和 1 的稀疏矩阵以及使用 R 中的 sqldf 包。

这是我的数据结构:

head(data)

  Fund                          Stock Type Shares.Held Maket.Value X..of.Portfolio Rank Change.in.Shares X..Change X..Ownership
1 12 WEST CAPITAL MANAGEMENT LP  GRUB CALL      500000    12100000          0.0173   12           500000       New          N/A
2 12 WEST CAPITAL MANAGEMENT LP  FIVE   SH      214521     6886000          0.0099   15           214521       New            0
3 12 WEST CAPITAL MANAGEMENT LP  SHAK   SH      314114    12439000          0.0178   11           307114      4387            1
4 12 WEST CAPITAL MANAGEMENT LP  FRSH   SH      324120     3650000          0.0053   16          -175880       -35            2
5 12 WEST CAPITAL MANAGEMENT LP  ATRA   SH      393700    10398000          0.0149   14           162003        69            1
6 12 WEST CAPITAL MANAGEMENT LP  ALNY   SH      651000    61285000          0.0875    4        No Change         0            1

【问题讨论】:

  • 听起来 data.table 可以做得很好。也许发布您的valuesdataobjects 的head,即提供有关数据结构的更多信息。欢呼

标签: r performance optimization matrix sparse-matrix


【解决方案1】:

我看到三个问题,按重要性递增的顺序排列:

(1) 您多次调用 rownames(values) 和 colnames(values),而不是在循环之外只调用一次。它可能有帮助,也可能没有帮助。

(2) 你在最里面的循环下计算A = data[data$Stock==rownames(values)[i],"Fund"],而你应该在这个循环之外计算它。

(3) 最重要的是:您的代码仅使用表格的两列:Fund 和 Stock。我看到在您的数据中,有许多行与 Fund 和 Stock 相同。您应该消除这种冗余。也许您想创建 data1=data[,c("Fund","Stock")] 并消除 data1 中的冗余行(无循环):

data1 = data1[,order(data1[,"Fund"])]
len = nrow(data1)
good = c(TRUE,data1[-len,1]!=data1[-1,1]|data1[-len,2]!=data1[-1,2])
data1 = data1[good,]

(上面的代码我没有测试)

也许您想更进一步,创建一个列表,为每个基金指定它包含的股票,没有冗余。

PS:您仍然可以创建列表,为每只股票指定哪些基金拥有它:

rv = rownames(values)
len = length(rv)
fund.list = list()
for (i in 1:len)
    fund.list[[,i]] = data[data$Stock==rv[i],"Fund"]
for (i in 1:len) {
    A = fund.list[[i]]
    for (j in i:len) {
        values[i, j] = length(intersect(A, fund.list[[j]]))
    }
}

【讨论】:

  • 谢谢,不幸的是,其中一些对#3很有帮助,我的数据中只有基金和股票之间没有真正多余的行:(
  • 在您的问题中提供的数据中有一对冗余 (12,WEST)
  • 哦,对不起,不,它没有对齐,基金是“12 West Capital Management LP”,股票是 GRUB,五...我会在问题中澄清并对齐它们
  • 添加了即使没有冗余也可以做的事情。
猜你喜欢
  • 2018-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多