所以可以说我有一个在2d空间中保存点的numpy数组,如下所示
np.array([[3, 2], [4, 4], [5, 4], [4, 2], [4, 6], [9, 5]])
我还有一个numpy数组,将每个点标记为一个数字,该数组是一维数组,其长度为点数组中的点数。
np.array([0, 1, 1, 0, 2, 1])
现在,我想从labels数组中获取具有索引的每个点的平均值。因此,对于所有标记为0的点,取这些点的平均值。 我目前解决此问题的方法是以下方法
return np.array([points[labels==k].mean(axis=0) for k in range(k)])
其中,k是标签数组中最大的数字,或者被称为标注点的方式的数量。
我想要一种不使用for循环的方法,也许我还没有发现一些numpy功能?
答案 0 :(得分:4)
方法1::在braodcasting
的帮助下,我们可以利用matrix-multiplication
-
mask = labels == np.arange(labels.max()+1)[:,None]
out = mask.dot(points)/np.bincount(labels).astype(float)[:,None]
样品运行-
In [36]: points = np.array([[3, 2], [4, 4], [5, 4], [4, 2], [4, 6], [9, 5]])
...: labels = np.array([0, 1, 1, 0, 2, 1])
# Original soln
In [37]: L = labels.max()+1
In [38]: np.array([points[labels==k].mean(axis=0) for k in range(L)])
Out[38]:
array([[3.5 , 2. ],
[6. , 4.33333333],
[4. , 6. ]])
# Proposed soln
In [39]: mask = labels == np.arange(labels.max()+1)[:,None]
...: out = mask.dot(points)/np.bincount(labels).astype(float)[:,None]
In [40]: out
Out[40]:
array([[3.5 , 2. ],
[6. , 4.33333333],
[4. , 6. ]])
方法2:使用np.add.at
-
sums = np.zeros((labels.max()+1,points.shape[1]),dtype=float)
np.add.at(sums,labels,points)
out = sums/np.bincount(labels).astype(float)[:,None]
方法3::如果labels
中存在从0到最大标签的序列中的所有数字,我们也可以使用np.add.reduceat
-
sidx = labels.argsort()
sorted_points = points[sidx]
sums = np.add.reduceat(sorted_points,np.r_[0,np.bincount(labels)[:-1].cumsum()])
out = sums/np.bincount(labels).astype(float)[:,None]