[英]Accessing a large number of unsorted array elements in Python
我對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)
...這些行在大約5分鍾內執行, length(organSets[[2]])=52960
, length(voxMap_beamlet_val) = length(voxMap_beamlet_iInd) = 1217077
但是,在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])
請指教。
首先,您想要有效地訪問行,而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,則最后一行的除法是整數除法。 因為len(orgVox)
至少和分子一樣大,所以這里總是產生0或1。 生成level
的划分可能存在類似的問題,具體取決於您正在使用的數據的dtype。 要啟用真正的划分,您可以
from __future__ import division
在文件的頂部。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.