从pandas groupby返回聚合的dataframe
我正在努力理解Pandas的groupby方法。我想写一个函数,做一些聚合操作,然后返回一个Pandas的DataFrame。这里有一个非常简单的例子,使用了sum()函数。我知道对于简单的求和,有更简单的方法,但在实际应用中,我的函数要复杂得多:
import pandas as pd
df = pd.DataFrame({'col1': ['A', 'A', 'B', 'B'], 'col2':[1.0, 2, 3, 4]})
In [3]: df
Out[3]:
col1 col2
0 A 1
1 A 2
2 B 3
3 B 4
def func2(df):
dfout = pd.DataFrame({ 'col1' : df['col1'].unique() ,
'someData': sum(df['col2']) })
return dfout
t = df.groupby('col1').apply(func2)
In [6]: t
Out[6]:
col1 someData
col1
A 0 A 3
B 0 B 7
我没想到会在结果中看到两次col1
,也没想到会出现那个神秘的索引。我真的以为我只会得到col1
和someData
。
在我的实际应用中,我是按多个列进行分组的,真的希望能得到一个DataFrame,而不是一个Series对象。
有没有什么解决方案或者对我上面例子的解释?
----- 添加的信息 -----
我觉得我应该先从这个例子开始:
In [13]: import pandas as pd
In [14]: df = pd.DataFrame({'col1':['A','A','A','B','B','B'], 'col2':['C','D','D','D','C','C'], 'col3':[.1,.2,.4,.6,.8,1]})
In [15]: df
Out[15]:
col1 col2 col3
0 A C 0.1
1 A D 0.2
2 A D 0.4
3 B D 0.6
4 B C 0.8
5 B C 1.0
In [16]: def func3(df):
....: dfout = sum(df['col3']**2)
....: return dfout
....:
In [17]: t = df.groupby(['col1', 'col2']).apply(func3)
In [18]: t
Out[18]:
col1 col2
A C 0.01
D 0.20
B C 1.64
D 0.36
在上面的例子中,apply()
函数的结果是一个Pandas的Series。而且它缺少了来自df.groupby
的分组列。我现在面临的主要问题是,如何创建一个函数,应用于groupby后,既能返回函数的结果,又能返回用于分组的列?
----- 又一个更新 ------
看起来如果我这样做:
pd.DataFrame(t).reset_index()
我得到了一个非常接近我想要的DataFrame。
1 个回答
8
你看到的那些0的列是因为.unique()
的输出是一个数组。
想要理解你的apply是怎么工作的,最好的办法是逐个检查每个动作,按组来看:
In [11] :g = df.groupby('col1')
In [12]: g.get_group('A')
Out[12]:
col1 col2
0 A 1
1 A 2
In [13]: g.get_group('A')['col1'].unique()
Out[13]: array([A], dtype=object)
In [14]: sum(g.get_group('A')['col2'])
Out[14]: 3.0
大多数情况下,你希望这个是一个聚合的值。
grouped.apply
的输出总是会把组标签作为索引(也就是'col1'的唯一值),所以你构建col1
的方式对我来说有点难以理解。
注意:如果想把'col1'
(索引)变回一列,你可以使用reset_index
,在这种情况下。
In [15]: g.sum().reset_index()
Out[15]:
col1 col2
0 A 3
1 B 7