我有两个大小相同的二维numpy数组(在本例中对大小和内容进行简化)。
ID矩阵:
1 1 1 2 2
1 1 2 2 5
1 1 2 5 5
1 2 2 5 5
2 2 5 5 5以及一个价值矩阵:
14.8 17.0 74.3 40.3 90.2
25.2 75.9 5.6 40.0 33.7
78.9 39.3 11.3 63.6 56.7
11.4 75.7 78.4 88.7 58.6
79.6 32.3 35.3 52.5 13.3我的目标是计数和求和第二个矩阵的值,这些值按第一个矩阵的is分组:
1: (8, 336.8)
2: (9, 453.4)
5: (8, 402.4)我可以在for循环中做到这一点,但是当矩阵的大小为数千,而不是只有5x5和数千个唯一ID时,处理起来需要很长时间。
numpy 是否有一个聪明的方法或组合的方法来完成此操作?
发布于 2016-04-15 09:40:52
下面是一种矢量化的方法,用于获取ID和ID-based的计数和value的总和,并将np.unique和np.bincount结合在一起-
unqID,idx,IDsums = np.unique(ID,return_counts=True,return_inverse=True)
value_sums = np.bincount(idx,value.ravel())要获得作为字典的最终输出,可以使用循环理解来收集求和值,如下所示-
{i:(IDsums[itr],value_sums[itr]) for itr,i in enumerate(unqID)}样本运行-
In [86]: ID
Out[86]:
array([[1, 1, 1, 2, 2],
[1, 1, 2, 2, 5],
[1, 1, 2, 5, 5],
[1, 2, 2, 5, 5],
[2, 2, 5, 5, 5]])
In [87]: value
Out[87]:
array([[ 14.8, 17. , 74.3, 40.3, 90.2],
[ 25.2, 75.9, 5.6, 40. , 33.7],
[ 78.9, 39.3, 11.3, 63.6, 56.7],
[ 11.4, 75.7, 78.4, 88.7, 58.6],
[ 79.6, 32.3, 35.3, 52.5, 13.3]])
In [88]: unqID,idx,IDsums = np.unique(ID,return_counts=True,return_inverse=True)
...: value_sums = np.bincount(idx,value.ravel())
...:
In [89]: {i:(IDsums[itr],value_sums[itr]) for itr,i in enumerate(unqID)}
Out[89]:
{1: (8, 336.80000000000001),
2: (9, 453.40000000000003),
5: (8, 402.40000000000003)}发布于 2016-04-15 09:34:42
只要结合几个简单的方法,就可以做到这一点:
numpy.unique查找每个ID这个可以是这样的:
import numpy as np
ids = np.array([[1, 1, 1, 2, 2],
[1, 1, 2, 2, 5],
[1, 1, 2, 5, 5],
[1, 2, 2, 5, 5],
[2, 2, 5, 5, 5]])
values = np.array([[14.8, 17.0, 74.3, 40.3, 90.2],
[25.2, 75.9, 5.6, 40.0, 33.7],
[78.9, 39.3, 11.3, 63.6, 56.7],
[11.4, 75.7, 78.4, 88.7, 58.6],
[79.6, 32.3, 35.3, 52.5, 13.3]])
for i in np.unique(ids): # loop through all IDs
mask = ids == i # find entries that match current ID
count = np.sum(mask) # number of matches
total = np.sum(values[mask]) # values of matches
print('{}: ({}, {:.1f})'.format(i, count, total)) #print result
# Output:
# 1: (8, 336.8)
# 2: (9, 453.4)
# 5: (8, 402.4)发布于 2016-04-15 10:47:13
索引包(免责声明:我是它的作者)具有以优雅和矢量化的方式解决此类问题的功能:
import numpy_indexed as npi
group_by = npi.group_by(ID.flatten())
ID_unique, value_sums = group_by.sum(value.flatten())
ID_count = groupy_by.count 注意:如果您想要计算和计数来计算平均值,也有group_by.mean;加上许多其他有用的功能。
https://stackoverflow.com/questions/36643216
复制相似问题