[英]Pandas Dataframe Groupby multiple columns then sum
假设每个 Python 代码如下:
import pandas as pd
import numpy as np
在 Pandas 中,如果我有一个 2 列的数据框,其中一个是数字数组,我可以对数组的值求和以获得单个数组。
df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar'], 'numbers' : [np.array([1, 2, 3, 4]),np.array([2, 4, 2, 4]),np.array([2, 3, 4, 5]),np.array([1, 3, 5, 7])]} )
df['arrays'].sum()
我什至可以按第一列分组,然后对第二列求和以获得每组的总和:
grpA = df.groupby('A')
grpA.sum()
但是,如果除了数组列之外我还有多个其他列,比如其他 2 列,那么当我尝试按前两列分组并对数组列求和时,我会得到一个ValueError: Function does not reduce
:
df2 = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar'],'B': ['la', 'la', 'al', 'al'],'numbers' : [np.array([1, 2, 3, 4]),np.array([2, 4, 2, 4]),np.array([2, 3, 4, 5]),np.array([1, 3, 5, 7])]} )
grpAB = df2.groupby(['A','B'])
grpAB.sum()
在 SQL 中,如果我可以对数组求和,以下内容将起作用:
select A, B, sum(numbers)
from df2
group by A, B
有没有办法成功地按多列分组并对 Pandas 中的最后一个数组列求和?
您可以使用lambda
表达式。 iat
表达式采用系列中第一个元素的标量值(这里只是数字列表),然后对结果求和。
>>> df2.groupby(['A', 'B']).numbers.apply(lambda x: x.iat[0].sum())
A B
bar al 16
la 12
foo al 14
la 10
Name: numbers, dtype: int64
一个可能的解决方案是
df2 = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar'],'B': ['la', 'la', 'al', 'al'],'numbers' : [np.array([1, 2, 3, 4]),np.array([2, 4, 2, 4]),np.array([2, 3, 4, 5]),np.array([1, 3, 5, 7])]} )
grouped = df2.groupby(['A','B'])
#set up empty arrays to append data from below loop
array=[]
index=[]
#loop through the grouped data and sum up the array numbers
for i,j in grouped:
array.append({'numbers':j.numbers.sum()})
index.append(i)
#put summed array back into a dataframe
print pd.DataFrame((array),index=index)
df2 = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar'],'B': ['la', 'la', 'al', 'al'],'numbers' : [np.array([1, 2, 3, 4]),np.array([2, 4, 2, 4]),np.array([2, 3, 4, 5]),np.array([1, 3, 5, 7])]} )
Out[42]:
A B numbers
0 foo la [1, 2, 3, 4]
1 bar la [2, 4, 2, 4]
2 foo al [2, 3, 4, 5]
3 bar al [1, 3, 5, 7]
grpAB = df2.groupby(['A','B'])
res = grpAB.apply(lambda x : x.numbers.sum())
Out[43]:
A B
bar al [1, 3, 5, 7]
la [2, 4, 2, 4]
foo al [2, 3, 4, 5]
la [1, 2, 3, 4]
dtype: object
pd.DataFrame(res , columns = ['numbers'])
Out[44]:
numbers
A B
bar al [1, 3, 5, 7]
la [2, 4, 2, 4]
foo al [2, 3, 4, 5]
la [1, 2, 3, 4]
# if you want to reset the index
pd.DataFrame(res , columns = ['numbers']).reset_index()
Out[45]:
A B numbers
0 bar al [1, 3, 5, 7]
1 bar la [2, 4, 2, 4]
2 foo al [2, 3, 4, 5]
3 foo la [1, 2, 3, 4]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.