在Python

时间:2015-06-08 00:25:03

标签: python r sparse-matrix large-data bigdata

我对Python不是很熟练。但是,我对R非常方便。但是,我必须使用Python,因为它有一个与Cplex的最新接口。我也试图避免在C / C ++中必须做的所有额外编码

话虽如此,我在大型列表/数组/矩阵上存在速度和效率方面的问题......

我很快在R中写了两行,这些行非常难看但工作得很好......

doses = sapply(organSets[[2]], function(x) sum(voxMap_beamlet_val[which(voxMap_beamlet_iInd[,1] == x),1]))
length(which(doses <= sum(doses)/length(organSets[[2]])))/length(doses)

... length(organSets[[2]])=52960length(voxMap_beamlet_val) = length(voxMap_beamlet_iInd) = 1217077

约5分钟后执行这些行

然而,在Python中,类似的东西大约需要两个小时。通过使用scipy.sparse,执行时间缩短了一半,大约一个小时......这显然是不可接受的......

Python代码如下......

voxMapBeamlet = sparse.coo_matrix((voxMap_beamlet_val,(voxMap_beamlet_iInd,voxMap_beamlet_jInd)),shape=(1055736,8500))
def getDose(voxInd):
    return sum([x.sum() for x in voxMapBeamlet.getrow(voxInd)])

def probDoseLevel2(orgVox,level=None):
    voxDose2 = [0] * len(orgVox)
    for i,v in enumerate(orgVox):
        voxDose2[i] = getDose(v)
    if level == None:
        level = sum(voxDose2)/len(orgVox)
    print len([x for x in voxDose2 if x <= level])/len(orgVox)

probDoseLevel2(organSets[1])

请告知。

1 个答案:

答案 0 :(得分:2)

首先,您希望有效地访问行,而COO格式不会这样做。将您的voxMapBeamlet转换为压缩稀疏行格式,getrow变得更加高效:

voxMapBeamlet = sparse.coo_matrix((voxMap_beamlet_val,(voxMap_beamlet_iInd,voxMap_beamlet_jInd)),shape=(1055736,8500))
voxMapBeamlet = voxMapBeamlet.tocsr()

其次,getDose比它需要的要复杂得多:

def getDose(voxInd):
    return voxMapBeamlet.getrow(voxInd).sum()

我怀疑这已经足够快了,但我们应该能够进一步推进它。我们可以使用广播和高级索引将更多的工作从Python字节码推送到C级例程中:

def probDoseLevel2(orgVox,level=None):
    relevantRows = voxMapBeamlet[orgVox]

    # Dense column matrix of row sums
    voxDose2 = relevantRows.sum(axis=1)
    if level is None:
        level = voxDose2.sum()/len(orgVox)
    return (voxDose2 <= level).sum() / len(orgVox)

最后,如果您使用的是Python 2,则最后一行中的除法是整数除法。这里总是会产生0或1,因为len(orgVox)至少和分子一样大。根据您正在使用的数据的类型,生成level的部门可能存在类似的问题。要启用真正的除法,您可以输入

from __future__ import division

位于文件顶部。