计算2D numpy阵列中每行内和每列内的非零元素
我有一个numpy矩阵,其中大多包含非零值,但偶尔会包含零值。我需要能够:
1.)计算每行中的非零值,并将该计数放入一个变量中,我可以在随后的操作中使用该变量,可能是迭代遍历行索引并在迭代过程中执行计算过程
2.)计数在每列中的非零值,并把该计数到我可以在后续操作中使用,也许通过列索引进行迭代,并且在迭代过程计算2D numpy阵列中每行内和每列内的非零元素
对于执行计算的可变例如,我需要做的一件事是对每行进行求和,然后将每行的总和除以每行的非零值的数量,为每个行索引报告单独的结果。然后我需要对每列进行求和,然后将列和除以列中非零值的数量,并且还为每个列索引报告单独的结果。我还需要做其他的事情,但在弄清楚我要在这里列出的事情后,他们应该很容易。
我正在使用的代码如下。你可以看到我创建了一个零数组,然后从一个csv文件中填充它。某些行将包含所有列的值,但其他行仍会在最后一列中保留一些零,从而产生上述问题。
以下代码的最后5行来自本论坛的另一篇文章,最后5行代码返回打印的零/行索引列表。但我不知道如何使用结果信息创建上述的非零行数和非零列数。谁能帮我这个?
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
元素的数量。
变量columns
和rows
包含非零数量的原始阵列的每一列/行中的值(元件!= 0):
columns = np.array([2, 1, 3])
rows = np.array([2, 3, 1])
EDIT:整个代码可能看起来像这(与原来的代码的一些简化):
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)
你想,如果有一列/行没有非零元素做什么?然后我们可以调整代码来解决这个问题。
'a.astype(bool)'将比'a!= 0'更快地工作(至少在int上) – joeln 2013-05-06 03:48:14
(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.
我不知道是否有一个更优雅的方式。
更快的方法是克隆你的矩阵而不是真正的值。然后,只需按行或列总结:这工作快50倍,我不是芬兰人奥雅纳尼尔森的解决方案(1票反对53秒)
X_clone = X.tocsc()
X_clone.data = np.ones(X_clone.data.shape)
NumNonZeroElementsByColumn = X_clone.sum(0)
NumNonZeroElementsByRow = X_clone.sum(1)
编辑: 也许你会需要NumNonZeroElementsByColumn翻译成1维阵列由
np.array(NumNonZeroElementsByColumn)[0]
一种快速的方法来计算每行的非零元素在SciPy的稀疏矩阵m
是:
np.diff(m.tocsr().indptr)
CSR矩阵的indptr
属性表示与行之间的边界相对应的数据内的索引。因此,计算每个条目之间的差异将提供每行中非零元素的数量。
类似地,对于每一列的非零元素的数目,可使用:
np.diff(m.tocsc().indptr)
如果数据已经在适当的形式,这些都将在O(m.shape[0]
)和ö运行(m.shape[1]
),而不是O(m.getnnz()
)在Marat和Finn的解决方案中。
如果需要行和列nozero计数,并说,m
已经是一个CSR,你可以使用:
row_nonzeros = np.diff(m.indptr)
col_nonzeros = np.bincount(m.indices)
这是不是渐近速度比第一转化为CSC(这是Ø (m.getnnz()
))得到col_nonzeros
,但由于实现细节更快。
'scipy.sparse.csr_matrix'和'csc_matrix'现在支持'getnnz(axis = 0)'和'getnnz (轴= 1)'使用这种方法。 – joeln 2015-09-27 01:03:49
真是啰嗦问一个很大的问题。 – dbliss 2015-05-09 03:06:49