gpt4 book ai didi

python - 对二维 numpy 数组执行分组运算

转载 作者:行者123 更新时间:2023-12-01 00:47:55 27 4
gpt4 key购买 nike

我有一个 2D numpy 数组(实际上是一个相似度矩阵),我需要在其上按 block 计算平均值。例如使用以下矩阵:

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 中的标签相对应的 block 的平均值。产生以下输出:

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. ]])

关于python - 对二维 numpy 数组执行分组运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56794019/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com