[英]Perform group operation on 2D numpy array
我有一个二维的numpy数组(实际上是一个相似矩阵),我需要在上面按块计算平均值。 例如,具有以下矩阵:
sima = np.array([[1,0.8,0.7,0.3,0.1,0.5],
[0.8,1,0.1,0.5,0.2,0.5],
[0.7,0.1,1,0.1,0.3,0.9],
[0.3,0.5,0.1,1,0.8,0.5],
[0.1,0.2,0.3,0.8,1,0.5],
[0.5,0.5,0.9,0.5,0.5,1]])
和标签向量:
labels = np.array([1,1,1,2,2,3])
这意味着矩阵的前三行(由于相似矩阵是对称的,因此也为列)对应于聚类1
,接下来的2对应于聚类2
,最后一个对应于聚类3
。
我需要计算sima
中与标签中的labels
相对应的块的平均值。 产生以下输出:
0.69 0.25 0.63
0.25 0.90 0.50
0.63 0.50 1.00
到目前为止,我有一个在标签和掩码数组上使用双循环的可行解决方案:
labels_matrix = np.tile(np.array(labels), (len(labels), 1))
output = pd.DataFrame(np.zeros(shape = (3,3)))
for i in range(3):
for j in range(3):
mask = (labels_matrix != j+1) | (labels_matrix.T != i+1)
output.loc[i,j] = np.mean(np.mean(np.ma.array(sima, mask = mask)))
该代码产生正确的输出,但是我的实际矩阵是50kx50k,并且此代码需要花费很多时间进行计算。 我怎样才能使其更快?
注意:我需要一个不同数量级的速度,因此我希望使用类似矩阵对称性之类的技巧是不够的。
对于排序标签,我们可以使用np.add.reduceat
In [62]: idx = np.flatnonzero(np.r_[True,labels[:-1] != labels[1:],True])
In [63]: c = np.diff(idx)
In [64]: sums = np.add.reduceat(np.add.reduceat(sima,idx[:-1],axis=0),idx[:-1],axis=1)
In [65]: sums/(c[:,None]*c)
Out[65]:
array([[0.68888889, 0.25 , 0.63333333],
[0.25 , 0.9 , 0.5 ],
[0.63333333, 0.5 , 1. ]])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.