Python 对2D NumPy数组的每行和每列中的非零元素进行计数
我有一个Python 对2D NumPy数组的每行和每列中的非零元素进行计数,python,arrays,count,numpy,Python,Arrays,Count,Numpy,我有一个NumPy矩阵,其中大部分包含非零值,但偶尔会包含零值。我需要能够: 对每行中的非零值进行计数,并将该计数放入一个变量中,我可以在后续操作中使用该变量,可以通过迭代行索引并在迭代过程中执行计算来实现 对每列中的非零值进行计数,并将该计数放入一个变量中,我可以在后续操作中使用该变量,可能是通过迭代列索引并在迭代过程中执行计算 例如,我需要做的一件事是对每行求和,然后将每行和除以每行中非零值的数量,为每行索引报告一个单独的结果。然后我需要对每列求和,然后将列和除以列中非零值的数量,同时为每列
NumPy
矩阵,其中大部分包含非零值,但偶尔会包含零值。我需要能够:
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))
ANOVAInputMatrixValuesArray=0([len(TestIDs),9],浮点)
j=0
对于范围(0,len(TestIDs))内的j:
TestID=str(TestID[j])
ReadOrWrite='Read'
文件名=输入文件名
directory=GetCurrentDirectory(返回正确目录的参数)
inputfile=open(目录'r')
reader=csv.reader(输入文件)
m=0
对于读取器中的行:
如果m
变量(a!=0)
是一个与原始a
形状相同的数组,它包含所有非零元素的True
.sum(x)
函数对轴x
上的元素求和。True/False
元素之和是True
元素的数量
变量列
和行
包含原始数组中每列/行中非零(元素!=0)值的数量:
columns = np.array([2, 1, 3])
rows = np.array([2, 3, 1])
编辑:整个代码可能如下所示(原始代码中有一些简化):
编辑2:
要获取所有列/行的平均值,请使用以下命令:
colMean = a.sum(0) / (a != 0).sum(0)
rowMean = a.sum(1) / (a != 0).sum(1)
如果列/行中没有非零元素,您想做什么?然后我们可以调整代码来解决这样的问题。(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.
我想知道是否有更优雅的方法。更快的方法是用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Årup Nielsen的解决方案快50倍(1秒对53秒)
编辑:
也许您需要将NumNonZeroElementsByColumn转换为一维数组
在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_非零
)的速度快,但由于实现细节,速度更快。对于稀疏矩阵,请使用CSR/CSC矩阵支持的getnnz()
函数
例如
a.astype(bool)
比a!=0
问一个好问题的方式非常冗长。scipy.sparse.csr_matrix
和csc_matrix
现在使用这种方法支持getnnz(axis=0)
和getnnz(axis=1)
。
np.diff(m.tocsr().indptr)
np.diff(m.tocsc().indptr)
row_nonzeros = np.diff(m.indptr)
col_nonzeros = np.bincount(m.indices)
a = scipy.sparse.csr_matrix([[0, 1, 1], [0, 1, 0]])
a.getnnz(axis=0)
array([0, 2, 1])