我有一个算法,它需要一个N个数的可变向量wgts,根据M×N整数矩阵bins中的类别求和。例如,如果“wgts”的初始值是[0.2、0.4、0.3、0.1、0.7、0.6],而B是[[0、1、2、2、0、1],[2、2、0、0、1、1]],则结果将是[[(0.2+0.7),(0.4+0.6),(0.3+0.1)],[(0.7+0.6),(0.2+0.4),(0.3+0.1)]
我需要用一个固定的分类矩阵“bins”和改变向量“wgts”来重复这个过程。当M和N变大时,这个过程需要很多时间。我发现python包numpy有一个有用且快速的函数bincount。我想使用R,因为我的进程的其余部分都在R中,但是到目前为止,我还不能像Python那样快速地在R中修改我的算法
到目前为止,R中工作最快的方法是保存独立的逻辑M-by-N矩阵,每个类别一个。然而,它仍然需要大约两倍于我的Python脚本的时间,我假设它需要更多的内存,尽管我不知道如何度量这部分。下面是我的Python和R脚本及其处理时间。你知道吗
# R First attempt, "straightforward"
smplSize <- 1000000
binTypes <- 100
nIter <- 20
set.seed(1)
bins <- matrix(floor(runif(smplSize * binTypes, min=0, max=5)),
nrow = smplSize)
wgts <- runif(smplSize)
tic <- Sys.time()
for (i in (1:nIter)) {
res <- matrix(nrow=5, ncol=binTypes)
for (j in 0:4) {
res[j+1,] <- colSums(wgts * (bins == j))
}
# Some process that modifies wgts based on res
}
toc <- Sys.time()
toc - tic # 117 seconds
# Second attempt, storing category locations in separate mask matrices
tic <- Sys.time()
# Store 5 matrices identifying locations of the integers 0 - 4
binMask <- list()
for (i in 0:4) {
binMask[[i+1]] <- bins == i
}
for (i in (1:nIter)) {
res <- matrix(nrow=5, ncol=binTypes)
for (j in 0:4) {
res[j+1,] <- colSums(wgts * binMask[[j + 1]])
}
# Some process that modifies wgts based on res
}
toc <- Sys.time()
toc - tic # 72 seconds
print(object.size(binMask), units = "Gb") # 1.9 Gb
import numpy as np
import timeit
import sys
smplSize = 1000000
nBins = 100
nIter = 20
wgts = np.random.random_sample(smplSize)
bins = np.random.randint(0, 5, (smplSize, nBins))
tic=timeit.default_timer()
res = np.bincount(bins, wgts)
toc=timeit.default_timer()
toc - tic
tic=timeit.default_timer()
for i in range(nIter):
res = np.apply_along_axis(np.bincount, 0, bins, wgts)
toc=timeit.default_timer()
toc - tic # 39 seconds
sys.getsizeof(bins)/(1024 ** 2) # 381 Mb
我正在64位Windows桌面上运行r3.4.4和python3.6.1,采用intelxeon CPU E5-2680,96gbram。你知道吗
我已经研究了Python是否以某种方式缓存了计算,但事实似乎并非如此。你知道吗
我玩过一点数据表“group”计算,但我还没有想出一个好方法来处理多个列到group by。你知道吗
在R中,为了检查计算精度,res[1,1]的值是99967.64
也许和数据表,但我们需要先改变垃圾箱的结构:
剩下的:
但也许这不符合你的需要,因为你提到你也在做循环中的其他事情。。。你知道吗
仅计时20次的总和:
不像python那么快,但是我们用100x5组求100e6个元素的和是有意义的。你知道吗
但在这种情况下,你需要在求和后对结果进行不同的处理。。。你知道吗
相关问题 更多 >
编程相关推荐