2 回答

TA貢獻(xiàn)1725條經(jīng)驗(yàn) 獲得超8個(gè)贊
如果的所有元素matrix都 >=0,那么您可以執(zhí)行以下操作:
np.percentile(matrix[np.any(matrix, axis = 1)], p, axis = 0)
這使用了這樣一個(gè)事實(shí),即任何浮點(diǎn)數(shù)或整數(shù)都0被解釋為T(mén)rue當(dāng)被視為布爾值時(shí)(np.any在內(nèi)部執(zhí)行)。使您無(wú)需單獨(dú)構(gòu)建那個(gè)大的布爾矩陣。
由于您在 中進(jìn)行布爾索引matrix[...],因此您正在創(chuàng)建一個(gè)臨時(shí)副本,您并不真正關(guān)心它是否在此percentile過(guò)程中被覆蓋。因此,您可以使用它overwrite_input = True來(lái)節(jié)省更多內(nèi)存。
mat = matrix.copy()
perc = np.percentile(matrix[np.any(matrix, axis = 1)], p, axis = 0, overwrite_input = True)
np.array_equals(mat, matrix) # is `matrix` still the same?
True
最后,這取決于你的其他archetecture,我建議你尋找到做matrix的一些味道scipy.sparse,(雖然有一些缺點(diǎn),這取決于你所使用的類(lèi)型),這應(yīng)該siginficantly再次減少內(nèi)存的使用情況。

TA貢獻(xiàn)1793條經(jīng)驗(yàn) 獲得超6個(gè)贊
我將其作為答案,因?yàn)樵u(píng)論中包含的內(nèi)容太多了,盡管它可能不完整。有兩個(gè)可疑的事情 - 如果您的機(jī)器有 200Gb 的可用內(nèi)存,那么第一個(gè)百分位數(shù)應(yīng)該在 20Gb 矩陣上運(yùn)行良好。那是很多內(nèi)存,所以開(kāi)始研究還有什么可能會(huì)使用它。從top- 是否有其他進(jìn)程或您的 python 程序使用所有這些?
第二個(gè)可疑的事情是文檔utils.percentile與它的實(shí)際行為不匹配。這是您鏈接到的代碼中的相關(guān)位:
def percentile(matrix, p):
"""
Estimation of percentile without zeros.
....
Returns
-------
float
Calculated percentile.
"""
return np.percentile(matrix[np.any(matrix > 0, axis=1)], p, axis=0)
它實(shí)際做的是返回為不全為零的行計(jì)算的(按列)百分位數(shù)。編輯那是包含至少一個(gè)正元素的行。如果值是非負(fù)的,那是一樣的,但總的來(lái)說(shuō),這將是一個(gè)非常不同的結(jié)果。
np.any(matrix > 0, axis=1)返回一個(gè)布爾數(shù)組來(lái)索引不全為零的行。例如
>>> np.any(array([[3, 4], [0, 0]]) > 0, axis=1)
array([ True, False])
>>> np.any(array([[3, 4], [1, 0]]) > 0, axis=1)
array([ True, True])
>>> np.any(array([[3, 0], [1, 0]]) > 0, axis=1)
array([ True, True])
該數(shù)組用于 index matrix,它僅選擇不全為零的行并返回那些行。如果您不熟悉這種索引方式,您應(yīng)該閱讀用于索引的 numpy 文檔。
計(jì)算需要大量?jī)?nèi)存 -matrix > 0創(chuàng)建一個(gè)與矩陣維度相同的布爾數(shù)組,然后索引創(chuàng)建一個(gè)matrix可能包含大部分行的副本。
因此,布爾數(shù)組可能為 2-4Gb,副本可能接近 20Gb。
可以減少,
## Find rows with all zeros, one row at a time to reduce memory
mask = [np.any(r > 0) for r in matrix]
## Find percentile for each column, excluding rows with all zeros
perc = [np.percentile(c[mask], p) for c in matrix.T]
但是,如前所述,這與功能文檔不匹配。
這種邏輯可能是有原因的,但很奇怪。如果您不知道原因,您可能可以np.percentile直接調(diào)用- 只需檢查它是否為較小的數(shù)據(jù)子集返回了一個(gè)接近值。還有nanpercentile, 可以以相同的方式使用,但忽略nan值。
您可以使用布爾索引來(lái)替換您不想包含在nan(ie matrix[matrix < 0] = np.nan) 中的值,然后調(diào)用它。
添加回答
舉報(bào)