簡體   English   中英

計算2D NumPy數組中每行和每列內的非零元素

[英]Counting non-zero elements within each row and within each column of a 2D NumPy array

我有一個NumPy矩陣,主要包含非零值,但有時會包含零值。 我需要能夠:

  1. 計算每行中的非零值,並將該計數放入我可以在后續操作中使用的變量中,可能通過迭代行索引並在迭代過程中執行計算。

  2. 計算每列中的非零值,並將該計數放入我可以在后續操作中使用的變量中,可能通過迭代列索引並在迭代過程中執行計算。

例如,我需要做的一件事是對每一行求和,然后將每行和除以每行中的非零值的數量,為每個行索引報告單獨的結果。 然后我需要對每列進行求和,然后將列總和除以列中非零值的數量,同時為每個列索引報告單獨的結果。 我還需要做其他事情,但在我弄清楚如何處理我在這里列出的內容后,它們應該很容易。

我正在使用的代碼如下。 您可以看到我正在創建一個零數組,然后從csv文件中填充它。 某些行將包含所有列的值,但其他行仍會在某些最后一列中保留一些零,從而產生上述問題。

以下代碼的最后五行來自此論壇上的另一個帖子。 最后五行代碼返回零的行/列索引的打印列表。 但是,我不知道如何使用該結果信息來創建上述的非零行計數和非零列計數。

ANOVAInputMatrixValuesArray=zeros([len(TestIDs),9],float)
j=0
for j in range(0,len(TestIDs)):
    TestID=str(TestIDs[j])
    ReadOrWrite='Read'
    fileName=inputFileName
    directory=GetCurrentDirectory(arguments that return correct directory)
    inputfile=open(directory,'r')
    reader=csv.reader(inputfile)
    m=0
    for row in reader:
        if m<9:
            if row[0]!='TestID':
                ANOVAInputMatrixValuesArray[(j-1),m]=row[2]
                m+=1
    inputfile.close()

IndicesOfZeros = indices(ANOVAInputMatrixValuesArray.shape) 
locs = IndicesOfZeros[:,ANOVAInputMatrixValuesArray == 0]
pts = hsplit(locs, len(locs[0]))
for pt in pts:
    print(', '.join(str(p[0]) for p in pt))

誰能幫我這個?

import numpy as np

a = np.array([[1, 0, 1],
              [2, 3, 4],
              [0, 0, 7]])

columns = (a != 0).sum(0)
rows    = (a != 0).sum(1)

變量(a != 0)是與原始a相同形狀的數組,並且對於所有非零元素包含True

.sum(x)函數對軸x的元素求和。 總和True/False元素是多少True元。

變量columnsrows包含原始數組的每列/每行中的非零(元素!= 0)值的數量:

columns = np.array([2, 1, 3])
rows    = np.array([2, 3, 1])

編輯 :整個代碼可能看起來像這樣(在原始代碼中有一些簡化):

ANOVAInputMatrixValuesArray = zeros([len(TestIDs), 9], float)
for j, TestID in enumerate(TestIDs):
    ReadOrWrite = 'Read'
    fileName = inputFileName
    directory = GetCurrentDirectory(arguments that return correct directory)
    # use directory or filename to get the CSV file?
    with open(directory, 'r') as csvfile:
        ANOVAInputMatrixValuesArray[j,:] = loadtxt(csvfile, comments='TestId', delimiter=';', usecols=(2,))[:9]

nonZeroCols = (ANOVAInputMatrixValuesArray != 0).sum(0)
nonZeroRows = (ANOVAInputMatrixValuesArray != 0).sum(1)

編輯2

要獲取所有列/行的平均值,請使用以下命令:

colMean = a.sum(0) / (a != 0).sum(0)
rowMean = a.sum(1) / (a != 0).sum(1)

如果列/行中沒有非零元素,您想要做什么? 然后我們可以調整代碼來解決這個問題。

在scipy稀疏矩陣m每行計算非零元素的快速方法是:

np.diff(m.tocsr().indptr)

CSR矩陣的indptr屬性指示數據內與行之間的邊界對應的索引。 因此,計算每個條目之間的差異將提供每行中非零元素的數量。

同樣,對於每列中的非零元素數,請使用:

np.diff(m.tocsc().indptr)

如果數據已經是適當的形式,它們將分別在O( m.shape[0]O( m.shape[1] )中運行 ,而不是在Marat和Finn的解決方案中運行O( m.getnnz()

如果您需要行和列nozero計數,並且,例如, m已經是CSR,您可以使用:

row_nonzeros = np.diff(m.indptr)
col_nonzeros = np.bincount(m.indices)

這並不比第一次轉換到CSC(即O( m.getnnz()獲得col_nonzeros速度快,但由於實現細節而更快。

更快的方法是使用1而不是實際值來克隆矩陣。 然后只按行或列總結:

X_clone = X.tocsc()
X_clone.data = np.ones( X_clone.data.shape )
NumNonZeroElementsByColumn = X_clone.sum(0)
NumNonZeroElementsByRow = X_clone.sum(1)

對我來說,這比FinnÅrupNielsen的解決方案快了50倍(1秒對53)

編輯:也許您需要將NumNonZeroElementsByColumn轉換為1維數組

np.array(NumNonZeroElementsByColumn)[0]

(a!= 0)對於我目前的scipy版本中的稀疏矩陣(scipy.sparse.lil_matrix)不起作用。

對於稀疏矩陣,我做了:

    (i,j) = X.nonzero()
    column_sums = np.zeros(X.shape[1])
    for n in np.asarray(j).ravel():
        column_sums[n] += 1.

我想知道是否有更優雅的方式。

對於稀疏矩陣,請使用CSR / CSC矩陣支持的getnnz()函數。

例如

a = scipy.sparse.csr_matrix([[0, 1, 1], [0, 1, 0]])
a.getnnz(axis=0)

array([0, 2, 1])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM