我希望找到与另一个numpy匹配的索引对应的行的和。
下面的示例更好地演示了这一点。
A=np.array(['a-1','b-1','b-1','c-2','a-1','b-1','c-2']);
b = np.array([1.21,2.34,1.2,2.8,10.0,0.9,8.4]);;我宁愿输出结果是字典,这样
d['a-1'] = 1.21 + 10.0 = 11.21
d['b-1'] = 2.34 + 1.2 + 0.9 = 4.44
d['c-2'] = 2.8 + 8.4 = 11.2结果是b数组的元素与A数组中出现相同值的索引对应的元素之和。有什么有效的办法吗?我的数组很大(数以百万计)
发布于 2017-11-21 09:43:00
方法#1
我们可以结合使用np.unique和np.bincount -
In [48]: unq, ids = np.unique(A, return_inverse=True)
In [49]: dict(zip(unq, np.bincount(ids, b)))
Out[49]:
{'a-1': 11.210000000000001,
'b-1': 4.4400000000000004,
'c-2': 11.199999999999999}因此,np.unique为A中的每个字符串提供了唯一的整数映射,然后将这些字符串输入给np.bincount,后者使用这些整数作为基于bin的加权求和的回收箱,其中包含来自b的权重。
方法#2 (特例)
假设A中的字符串总是3字符,一个更快的方法是将这些字符串转换为数字,然后将这些字符串用作np.unique的输入。其想法是,np.unique使用数字比字符串工作得更快。
因此,实施将是-
In [141]: n = A.view(np.uint8).reshape(-1,3).dot(256**np.arange(3))
In [142]: unq, st, ids = np.unique(n, return_index=1, return_inverse=1)
In [143]: dict(zip(A[st], np.bincount(ids, b)))
Out[143]:
{'a-1': 11.210000000000001,
'b-1': 4.4400000000000004,
'c-2': 11.199999999999999}神奇之处在于,重塑后的viewing保持为视图,因此应该非常有效:
In [150]: np.shares_memory(A,A.view(np.uint8).reshape(-1,3))
Out[150]: True或者我们可以使用axis参数np.unique (1.13.0中添加的功能)-
In [160]: A2D = A.view(np.uint8).reshape(-1,3)
In [161]: unq, st, ids = np.unique(A2D, axis=0, return_index=1, return_inverse=1)
In [162]: dict(zip(A[st], np.bincount(ids, b)))
Out[162]:
{'a-1': 11.210000000000001,
'b-1': 4.4400000000000004,
'c-2': 11.199999999999999}发布于 2017-11-21 09:51:43
另一种方法,使用熊猫
import pandas as pd
df = pd.DataFrame(data=[pd.Series(A),pd.Series(b)]).transpose()
res = df.groupby(0).sum()给出
res
Out[62]:
1
0
a-1 11.21
b-1 4.44
c-2 11.20你可以得到你想要的这样的东西:
res_dict = res[1].to_dict()这给
Out[64]:
{'a-1': 11.210000000000001,
'b-1': 4.4400000000000004,
'c-2': 11.199999999999999}发布于 2017-11-21 10:11:25
索引包(dsiclaimer: I是它的作者)包含了以高效和优雅的方式执行这些类型操作的功能:
import numpy_indexed as npi
k, v = npi.group_by(A).sum(b)
d = dict(zip(k, v))我觉得熊猫的分组语法很笨拙,不需要把你的数据重组成一个新的数据结构来执行这样的基本操作。
https://stackoverflow.com/questions/47409777
复制相似问题