繁体   English   中英

优化填充矩阵的速度

[英]Optimizing Speed for Populating a Matrix

我正在尝试在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

我看到三个问题,按照重要性的提高顺序排列:

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

(2)您应在最内层循环下计算A = data[data$Stock==rownames(values)[i],"Fund"] ,而应在此循环外进行计算。

(3)最重要:您的代码仅使用表的两列:资金和股票。 我发现您的数据中有很多行具有相同的“基金”和“股票”。 您应该消除这种冗余。 也许您想创建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]]))
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM