【问题标题】:Pandas group by custom functionPandas 按自定义功能分组
【发布时间】:2016-03-14 03:59:10
【问题描述】:

这应该很简单。我想要的是能够按函数的结果进行分组,就像在 SQL 中您可以按表达式进行分组一样:

SELECT substr(name, 1) as letter, COUNT(*) as count
FROM table
GROUP BY substr(name, 1)

这将计算名称列以字母表中每个字母开头的行数。

我想在 python 中做同样的事情,所以我假设我可以将一个函数传递给 groupby。但是,这只会将索引列(第一列)传递给函数,例如 0、1 或 2。我想要的是名称列:

import pandas

# Return the first letter
def first_letter(row):

    # row is 0, then 1, then 2 etc.
    return row.name[0]

#Generate a data set of words
test = pandas.DataFrame({'name': ["benevolent", "hidden", "absurdity", "anonymous", "furious", "antidemocratic", "honeydew"]})

#              name
# 0      benevolent
# 1          hidden
# 2       absurdity
# 3       anonymous
# 4         furious
# 5  antidemocratic
# 6        honeydew

test.groupby(first_letter)

我在这里做错了什么。如何按行索引以外的内容进行分组?

【问题讨论】:

    标签: python python-3.x pandas group-by aggregate-functions


    【解决方案1】:

    为第一个字母创建一个新列:

    def first_letter(row):
        return row[0]
    
    test['first'] = test['name'].apply(first_letter)
    

    并将其分组:

    group = test.groupby('first')
    

    使用它:

    >>> group.count()
    
         name
    first      
    a         3
    b         1
    f         1
    h         2
    

    【讨论】:

      【解决方案2】:

      您通常希望在字符串列上使用矢量化的str 运算符。使用get(0) 提取第一个字母,然后在groupby 操作中使用。最后,我们对结果进行count

      这是working with text data 的 Pandas 文档的链接。

      请注意,您可以将正则表达式模式用于extract 更复杂的表达式。

      >>> test.groupby(test['name'].str.get(0))['name'].count()
      name
      a       3
      b       1
      f       1
      h       2
      Name: name, dtype: int64
      

      更一般地说,您的函数应该返回数据框中的唯一项目,在这些项目上与其索引隐式分组。

      例如,对数字进行四舍五入的函数可用于对四舍五入的数字进行分组。

      df = pd.DataFrame({'A': [0.25, 0.75, 2.6, 2.7, 2.8]})
      
      >>> np.round(df.A)
      0    0
      1    1
      2    3
      3    3
      4    3
      Name: A, dtype: float64
      
      >>> df.groupby(np.round(df.A)).mean()
            A
      A      
      0  0.25
      1  0.75
      3  2.70
      

      自定义函数应应用于一系列数据框,例如布尔运算符:

      def ge_two(series):
          return series >= 2
      
      >>> df.groupby(ge_two(df.A)).sum()
               A
      A         
      False  1.0
      True   8.1
      

      【讨论】:

      • 虽然这适用于本示例,但我的实际数据不是字符串。我正在寻找的是一种按函数结果分组的通用方法
      • 感谢您的编辑。这更有意义。因此,为了避免向数据框中添加新列,我可以创建一个函数,该函数根据您对 ge_two 所做的系列返回一个数组
      • np.round(df.A) 实际上返回一个系列,其中包含一个索引和从函数返回的值,然后将用于分组。在接受的答案中,函数的值被存储回数据框中,然后在索引和分组值之间进行对齐。
      • 是的,这证实了我的想法。我实际上更喜欢这个答案,因为它不需要添加新系列
      • df.groupby(np.round(df.A)) 对我很有帮助,非常感谢!
      猜你喜欢
      • 2017-01-15
      • 2021-04-11
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 2015-06-20
      • 2017-11-05
      • 2014-08-09
      • 2019-03-26
      相关资源
      最近更新 更多