Pandas - 根据另一个列表中的索引对列表中的值求和

Posted

技术标签:

【中文标题】Pandas - 根据另一个列表中的索引对列表中的值求和【英文标题】:Pandas - Sum values in list according to index from another list 【发布时间】:2019-08-10 22:39:15 【问题描述】:

由于我要处理大量数据,因此我正在尝试找到最符合 Python 标准的方法来在尽可能短的时间内解决我的问题。我的问题如下:

我有两个列表

a = [12,34,674,2,0,5,6,8]
b = ['foo','bar','bar','foo','foo','bar','foo','foo']

我想说python:如果'bar'在b中,则取所有索引并将列表a中的所有值与这些索引相加。

这是我到目前为止所做的:

idx = [i for i, j in enumerate(a) if j == 'bar'] 

但后来我被堆叠了。我正在考虑使用一些有线 for 循环。你有什么想法吗?

【问题讨论】:

sum([a[i] for i, j in enumerate(b) if j == 'bar'] ).. ? 【参考方案1】:

numpy:

import numpy as np

a = np.array(a)
b = np.array(b)

a[b == 'bar'].sum()

【讨论】:

这可能是最快的方法 +1【参考方案2】:

使用np.bincount。计算总和('foo' 和 'bar')。

sum_foo, sum_bar = np.bincount(np.char.equal(b, 'bar'), a)
sum_foo
# 28.0
sum_bar
# 713.0

注意np.char.equal 适用于列表和数组。如果 b 是一个数组,那么可以使用b == 'bar' 代替,速度会快一些。

时间安排:

尽管这会计算两个总和,但它实际上非常快:

timeit(lambda: np.bincount(b == 'bar', a))
# 2.406161994993454

例如与 numpy 掩码方法比较:

timeit(lambda: a[b == 'bar'].sum())
# 5.642918559984537

在较大的阵列上,掩码会稍微快一些,这是预期的,因为 bincount 基本上完成了 2 倍的工作。仍然bincount 花费不到 2 倍的时间,所以如果你碰巧需要两个总和('foo' 和 'bar'),bincount 仍然更快。

aa = np.repeat(a, 1000)
bb = np.repeat(b, 1000)
timeit(lambda: aa[bb == 'bar'].sum(), number=1000)
# 0.07860603698645718
timeit(lambda:np.bincount(bb == 'bar', aa), number=1000)
# 0.11229897901648656

【讨论】:

【参考方案3】:

用途:

l = [x for x,y in zip(a,b) if y == 'bar']

如果你想要索引:

l = [i for (i,x),y in zip(enumerate(a),b) if y == 'bar']

【讨论】:

【参考方案4】:

这在pandas中很容易做到:

In[5]:
import pandas as pd
a = [12,34,674,2,0,5,6,8]
b = ['foo','bar','bar','foo','foo','bar','foo','foo']
df = pd.DataFrame('a':a, 'b':b)
df

Out[5]: 
     a    b
0   12  foo
1   34  bar
2  674  bar
3    2  foo
4    0  foo
5    5  bar
6    6  foo
7    8  foo

In [8]: df.loc[df['b']=='bar','a'].sum()
Out[8]: 713

因此,我们在这里获取您的列表并为data arg 为DataFrame ctor 构造一个dict

df = pd.DataFrame('a':a, 'b':b)

然后我们只使用loc 屏蔽df,我们选择'b' == 'bar' 所在的行并选择'a' 列并调用sum()

df.loc[df['b']=='bar','a'].sum()

【讨论】:

以上是关于Pandas - 根据另一个列表中的索引对列表中的值求和的主要内容,如果未能解决你的问题,请参考以下文章

根据另一列从 Pandas 系列中的列表中选择元素

根据 Pandas 中另一列中的索引从列中获取数据

根据包含必须过滤的索引的另一个列表拆分列表

如何根据列表有条件地更新 Pandas 中的 DataFrame 列

使用索引值列表对 pandas 多索引数据框进行切片 [重复]

将列表中的索引附加到列表列表以创建 pandas df