首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与另一个数组匹配的索引对应的numpy数组元素的有效和

与另一个数组匹配的索引对应的numpy数组元素的有效和
EN

Stack Overflow用户
提问于 2017-11-21 09:39:38
回答 3查看 774关注 0票数 3

我希望找到与另一个numpy匹配的索引对应的行的和。

下面的示例更好地演示了这一点。

代码语言:javascript
复制
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]);;

我宁愿输出结果是字典,这样

代码语言:javascript
复制
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数组中出现相同值的索引对应的元素之和。有什么有效的办法吗?我的数组很大(数以百万计)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-11-21 09:43:00

方法#1

我们可以结合使用np.uniquenp.bincount -

代码语言:javascript
复制
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.uniqueA中的每个字符串提供了唯一的整数映射,然后将这些字符串输入给np.bincount,后者使用这些整数作为基于bin的加权求和的回收箱,其中包含来自b的权重。

方法#2 (特例)

假设A中的字符串总是3字符,一个更快的方法是将这些字符串转换为数字,然后将这些字符串用作np.unique的输入。其想法是,np.unique使用数字比字符串工作得更快。

因此,实施将是-

代码语言:javascript
复制
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保持为视图,因此应该非常有效:

代码语言:javascript
复制
In [150]: np.shares_memory(A,A.view(np.uint8).reshape(-1,3))
Out[150]: True

或者我们可以使用axis参数np.unique (1.13.0中添加的功能)-

代码语言:javascript
复制
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}
票数 4
EN

Stack Overflow用户

发布于 2017-11-21 09:51:43

另一种方法,使用熊猫

代码语言:javascript
复制
import pandas as pd
df = pd.DataFrame(data=[pd.Series(A),pd.Series(b)]).transpose()
res = df.groupby(0).sum()

给出

代码语言:javascript
复制
res
Out[62]: 
         1
0         
a-1  11.21
b-1   4.44
c-2  11.20

你可以得到你想要的这样的东西:

代码语言:javascript
复制
res_dict = res[1].to_dict()

这给

代码语言:javascript
复制
Out[64]: 
{'a-1': 11.210000000000001,
 'b-1': 4.4400000000000004,
 'c-2': 11.199999999999999}
票数 2
EN

Stack Overflow用户

发布于 2017-11-21 10:11:25

索引包(dsiclaimer: I是它的作者)包含了以高效和优雅的方式执行这些类型操作的功能:

代码语言:javascript
复制
import numpy_indexed as npi
k, v = npi.group_by(A).sum(b)
d = dict(zip(k, v))

我觉得熊猫的分组语法很笨拙,不需要把你的数据重组成一个新的数据结构来执行这样的基本操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47409777

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档