【问题标题】:how to use apply() on df.groupby() in pandas如何在 pandas 的 df.groupby() 上使用 apply()
【发布时间】:2020-12-02 17:29:27
【问题描述】:

我知道如何在 pandas 中使用 groupby() 来使用聚合函数,例如 mean、sum 等,但我想知道如何使用 apply() 来进一步应用我想要的函数。

例如,在这个数据集中有两家公司'1st'和'2nd':

import pandas as pd
raw_data = {'regiment': ['Nighthawks', 'Nighthawks', 'Nighthawks', 'Nighthawks', 'Dragoons', 'Dragoons', 'Dragoons', 'Dragoons', 'Scouts', 'Scouts', 'Scouts', 'Scouts'], 
        'company': ['1st', '1st', '2nd', '2nd', '1st', '1st', '2nd', '2nd','1st', '1st', '2nd', '2nd'], 
        'name': ['Miller', 'Jacobson', 'Ali', 'Milner', 'Cooze', 'Jacon', 'Ryaner', 'Sone', 'Sloan', 'Piger', 'Riani', 'Ali'], 
        'preTestScore': [4, 24, 31, 2, 3, 4, 24, 31, 2, 3, 2, 3],
        'postTestScore': [25, 94, 57, 62, 70, 25, 94, 57, 62, 70, 62, 70]}
df = pd.DataFrame(raw_data, columns = ['regiment', 'company', 'name', 'preTestScore', 'postTestScore'])

我想添加一列来映射名称的第一个字母和该字母出现的次数。例如:

list(df.groupby(['company'])['name'])
[('1st',
  0      Miller
  1    Jacobson
  4       Cooze
  5       Jacon
  8       Sloan
  9       Piger
  Name: name, dtype: object),
 ('2nd',
  2        Ali
  3     Milner
  6     Ryaner
  7       Sone
  10     Riani
  11       Ali
  Name: name, dtype: object)]

我想要一个如下所示的分组熊猫数据框:

company name_dict
1st     {'M':1, 'J':2 ..}
2nd     {'M':1, 'R':2, 'A': 1..}

如果数据框是使用 for 循环的列表,我会知道如何派生 name_dict,但是如何应用使用 pandas groupby 派生列的函数?该函数的输入应该是什么?

例如,假设函数是

def get_name_dict():
 ...

输入应该是什么,如何使用 groupby 将函数映射到 pandas 数据框?

补充:我问这个问题的原因是因为 apply() 比 for 循环工作得快,这个数据框中大约有 70K 行,使用列表和 for 循环效率不高。

【问题讨论】:

  • 问题 - apply 本质上是一个 for 循环。如果这就是你想要的,为什么不直接用普通的 python 运行这个过程呢?
  • @sammywemmy 数据框有 70K 行,apply() 的运行速度比 for 循环快,这是我所知道的
  • 有趣。我对此有所不同,尤其是对于字符串操作。不过,对于您的问题,您可以像使用 apply 函数一样应用该函数。您是否已经拥有该功能,所以我们可以测试并查看哪些地方可以进行一些修改或改进?
  • @sammywemmy 我问的是输入应该是什么—— get_name_dict() 的输入应该是一个列表还是一个系列?如果我将函数编写为输入是名称列表,它会起作用吗?
  • 为什么要一个字典数据框?

标签: python pandas dataframe group-by apply


【解决方案1】:

这是一种解决方法,遍历分组,这就是 apply 的作用:

{key: value.str[0].value_counts().to_dict()
for key, value in df.groupby("company").name}

{'1st': {'J': 2, 'M': 1, 'P': 1, 'S': 1, 'C': 1},
 '2nd': {'R': 2, 'A': 2, 'M': 1, 'S': 1}}

【讨论】:

    【解决方案2】:

    让我们试试collections.Counter

    import collections
    
    df.name.str[0].groupby(df['company']).apply(lambda x : [collections.Counter(x)]).str[0]
    
    Out[119]: 
    company
    1st    {'M': 1, 'J': 2, 'C': 1, 'S': 1, 'P': 1}
    2nd            {'A': 2, 'M': 1, 'R': 2, 'S': 1}
    Name: name, dtype: object
    

    【讨论】:

      猜你喜欢
      • 2021-12-04
      • 1970-01-01
      • 2017-01-27
      • 1970-01-01
      • 2020-09-17
      • 2013-02-25
      • 2021-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多