【问题标题】:A better way to perform grouped aggregation and sorting with pandas使用 pandas 执行分组聚合和排序的更好方法
【发布时间】:2017-12-25 13:37:15
【问题描述】:

我正在使用婴儿姓名数据源。数据是这样的

name   sex births year
Mary    F  7065   1880
Anna    F  2604   1880
Emma    F  2003   1880
...
Zariyan M   5     2016
Zarren  M   5     2016
Zaryn   M   5     2016

我们的目的是过滤掉 2011 年及以后的年份。然后,聚合重复项,按性别分组并按降序排序。输出是这样的。

sex name      births
F   Emma      121375
F   Sophia    117352
F   Olivia    111691
F   Isabella  103947
F   Ava        94507
M   Noah      110280
M   Mason     105104
M   Jacob     104722
M   Liam      103250
M   William    99144

我设法做到了,但我的代码确实效率低下且乏味。应该有更好的方法来做到这一点,但我不知道如何。这是我的代码。

bnames_2010 = bnames.loc[bnames['year'] > 2010]

a = bnames_2010.groupby(['sex', 'name'], sort=False)['births'].sum().reset_index()

b = a.sort(['sex', 'births'], ascending=False)

c = b.groupby('sex').head()

bnames_top5 = c.sort('sex')
print('bnames_top5')

【问题讨论】:

  • 我相信你的帖子更适合codereview.stackexchange.com
  • @diegoperini 我怀疑 Code Review 是否有足够的 pandas 专家来判断这段代码是否合适。

标签: python performance pandas dataframe optimization


【解决方案1】:

你排序的次数太多了。此外,groupby 执行排序,使您之前的排序无效。这是我的做法 -

df = df.query("year >= 2011")\                   
       .groupby(['name', 'sex'], sort=False, as_index=False))\    
       .births.sum()\                              
       .sort_values(['sex', 'births'], ascending=[True, False])
       .groupby('sex', sort=False)\
       .head(5)\
  1. queryyear 上的过滤器
  2. groupby 将按namesex 分组,并防止结果被排序
  3. sum 将按组对birth 求和
  4. sort_values 将按照 sex 的升序和出生的降序对结果进行排序。
  5. 另一个groupby + head 调用通过sex 检索前5 行(可选)

【讨论】:

  • 这很棒。谢谢。但是,我如何在一个数据框中获得男性和女性的前 5 名,就像我发布的那样?这是我刚刚做的方式。 df.groupby('sex').head()
  • @WilsonLiao 现在看看?
  • @WilsonLiao 不客气!我邀请您在当前代码和此代码之间进行时间比较,看看它们在性能方面的表现如何。
猜你喜欢
  • 1970-01-01
  • 2019-10-12
  • 2013-02-03
  • 2014-11-17
  • 2017-10-05
  • 1970-01-01
  • 2019-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多