Python pandas:df.apply()使用df.groupby()进行幕后计算

Python pandas:df.apply()使用df.groupby()进行幕后计算,python,pandas,dataframe,data-analysis,Python,Pandas,Dataframe,Data Analysis,我对df.apply()如何工作感到非常困惑。以下是我面临的问题之一: import seaborn as sns tips = sns.load_dataset("tips") tips['tip_pct'] = tips['tip'] / tips['total_bill'] tips.head() total_bill tip smoker day time size tip_pct 0 16.99 1.01 No Sun Di

我对
df.apply()
如何工作感到非常困惑。以下是我面临的问题之一:

import seaborn as sns
tips = sns.load_dataset("tips")
tips['tip_pct'] = tips['tip'] / tips['total_bill']

tips.head()

       total_bill   tip smoker  day    time  size   tip_pct
0       16.99  1.01     No  Sun  Dinner     2  0.059447
1       10.34  1.66     No  Sun  Dinner     3  0.160542
2       21.01  3.50     No  Sun  Dinner     3  0.166587
3       23.68  3.31     No  Sun  Dinner     2  0.139780
4       24.59  3.61     No  Sun  Dinner     4  0.146808
我正在尝试按
tips['tip\u pct']
列对
tips
进行排序。我可以直接应用
排序\u值

In [153]: tips.sort_values(by='tip_pct').head()
Out[153]: 
     total_bill   tip smoker  day    time  size   tip_pct
237       32.83  1.17    Yes  Sat  Dinner     2  0.035638
102       44.30  2.50    Yes  Sat  Dinner     3  0.056433
57        26.41  1.50     No  Sat  Dinner     2  0.056797
0         16.99  1.01     No  Sun  Dinner     2  0.059447
187       30.46  2.00    Yes  Sun  Dinner     5  0.065660
现在,我尝试先按
smoker
列对该数据帧进行分组,然后按
tip\u pct
列进行排序

In [156]: tips.groupby('smoker').apply(lambda x: x.sort_values(by='tip_pct')).head()
Out[156]: 
            total_bill   tip smoker   day    time  size   tip_pct
smoker                                                           
No     57        26.41  1.50     No   Sat  Dinner     2  0.056797
       0         16.99  1.01     No   Sun  Dinner     2  0.059447
       48        28.55  2.05     No   Sun  Dinner     3  0.071804
       146       18.64  1.36     No  Thur   Lunch     3  0.072961
       130       19.08  1.50     No  Thur   Lunch     2  0.078616
我试图理解
groupby
apply
是如何协同工作的,因此我尝试了以下方法,但失败了

In [157]: for name, group in tips.groupby('smoker'):
     ...:     group.apply(lambda x: x.sort_values(by='tip_pct'))
     ...:     
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-157-5b5096eaa4d6> in <module>()
      1 for name, group in tips.groupby('smoker'):
----> 2     group.apply(lambda x: x.sort_values(by='tip_pct'))
      3 

//anaconda/lib/python3.5/site-packages/pandas/core/frame.py in apply(self, func, axis, broadcast, raw, reduce, args, **kwds)
   4260                         f, axis,
   4261                         reduce=reduce,
-> 4262                         ignore_failures=ignore_failures)
   4263             else:
   4264                 return self._apply_broadcast(f, axis)

//anaconda/lib/python3.5/site-packages/pandas/core/frame.py in _apply_standard(self, func, axis, ignore_failures, reduce)
   4356             try:
   4357                 for i, v in enumerate(series_gen):
-> 4358                     results[i] = func(v)
   4359                     keys.append(v.name)
   4360             except Exception as e:

<ipython-input-157-5b5096eaa4d6> in <lambda>(x)
      1 for name, group in tips.groupby('smoker'):
----> 2     group.apply(lambda x: x.sort_values(by='tip_pct'))
      3 

TypeError: ("sort_values() got an unexpected keyword argument 'by'", 'occurred at index total_bill')
[157]中的
:对于名称,在tips.groupby('smoker')中分组:
…:group.apply(lambda x:x.sort_值(by='tip_pct'))
...:     
---------------------------------------------------------------------------
TypeError回溯(最近一次调用上次)
在()
1表示名称,在提示中分组。分组方式(“吸烟者”):
---->2组。应用(lambda x:x.sort_值(按class='tip_pct'))
3.
//应用中的anaconda/lib/python3.5/site-packages/pandas/core/frame.py(self、func、axis、broadcast、raw、reduce、args、**kwds)
轴线4260楼,
4261减少=减少,
->4262忽略故障=忽略故障)
4263其他:
4264返回自应用广播(f轴)
//标准中的anaconda/lib/python3.5/site-packages/pandas/core/frame.py(self、func、axis、ignore、reduce)
4356请尝试:
4357用于枚举中的i、v(系列):
->4358结果[i]=func(v)
4359键。追加(v.name)
4360例外情况除外,如e:
in(x)
1表示名称,在提示中分组。分组方式(“吸烟者”):
---->2组。应用(lambda x:x.sort_值(按class='tip_pct'))
3.
TypeError:(“sort_values()在索引total_bill'处获得意外的关键字参数'by'”)
我的理解是,失败的原因是
apply()
函数试图对每列的值进行
排序,因此
by
不适用于
series.sort\u values()
。然而,我并不理解为什么
groupby
没有任何问题。根据我的理解,
groupby
只是分割了数据集,因此它仍然是几个较小的数据帧,在应用
sort\u values()
时会出现上述问题

有人能解释一下为什么将
groupby
apply(sort\u values)
直接应用
sort\u values
到原始数据框中不会产生任何问题吗


提前谢谢

使用for循环,您将看到
group
这里是数据帧,由组键`for name,df.groupby('smoker')中的组拆分:print(group.sort_values(by='tip_pct'))`@Wen,我知道您的方法可以工作,但我不明白为什么
groupby
先将数据集拆分,然后再应用
sort_values(sort_values)
不会有任何问题。你知道原因吗?apply是一种for循环,所以在执行一个for循环后,会添加另一个for循环failed@Wen,我理解你的意思。但是,如果我直接应用
tips.apply(sort\u values)
,它也会有同样的问题。这就是为什么我想了解
apply()
groupby()
的幕后计算。似乎由
groupby()
创建的较小的数据集与
apply()
没有问题,但原始数据集有问题。