在《利用Python进行数据分析》第2章1880-2011年间全美婴儿姓名例子中,有一段代码:
def add_prop(group):
births = group.births.astype(float)
group['prop'] = births/births.sum()
return group
names = names.groupby(['year', 'sex']).apply(add_prop)
代码就几行,开始很难理解后来想通了。
一开始深陷误区,以为换成SQL语句形式:select year, sex, births/sum(births) from names group by year, sex; 那么结果形式应该是131*2行3列,计算的是每年男女性别各自占比,然而这段代码运行后输出却是1690784行5列:
Out[13]:
name sex births year prop
0 Mary F 7065 1880 0.077643
1 Anna F 2604 1880 0.028618
2 Emma F 2003 1880 0.022013
3 Elizabeth F 1939 1880 0.021309
4 Minnie F 1746 1880 0.019188
... .. ... ... ...
1690779 Zymaire M 5 2010 0.000003
1690780 Zyonne M 5 2010 0.000003
1690781 Zyquarius M 5 2010 0.000003
1690782 Zyran M 5 2010 0.000003
1690783 Zzyzx M 5 2010 0.000003
[1690784 rows x 5 columns]
这个数据量大,我们来换个样例数据更容易理解
import numpy as np
data = pd.DataFrame({'key1':list('aabba'),
'key2': ['one','two','one','two','one'],
'data1': np.random.randn(5),
'data2': np.random.randn(5)})
def f(group):
# group['sum'] = group.data1.sum()
return group
aa = data.groupby(['key1','key2']).apply(f)
bb = data.groupby(['key1','key2'])['data1'].apply(f)
创建一个dataframe,结果如下:
Out[104]:
data1 data2 key1 key2
0 -1.598788 -0.903670 a one
1 -2.513484 -1.516623 a two
2 0.927106 -0.154149 b one
3 -0.662557 -2.138815 b two
4 1.141637 -0.596960 a one
Out[105]:
0 -1.598788
1 -2.513484
2 0.927106
3 -0.662557
4 1.141637
In[118]:data.groupby(['key1','key2']).indices
Out[118]:
{('a', 'one'): array([0, 4]),
('a', 'two'): array([1]),
('b', 'one'): array([2]),
('b', 'two'): array([3])}
这样就看的很明显了,将data的每一行看作一个array,groupby()后如果不指定计算的字段的话,那么f(group)中的group默认传递的是data的每一行,
所以书中例子输出结果是在整个names的dataframe形式上再加一列,1690784行5列而非我理解的262行3列了。
本文探讨了在使用pandas进行数据分析时,`groupby().apply()`操作的原理。通过一个实例,解释了为何代码结果与预期的SQL语句不同,指出在`groupby()`后如果没有指定计算字段,`apply()`会将每行数据作为一个数组处理,从而导致输出结果包含原始数据的所有行,并新增一列。通过对样例数据的操作,帮助读者更清晰地理解这一概念。
1048

被折叠的 条评论
为什么被折叠?



