【问题标题】:Pandas: apply different functions to different columns熊猫:将不同的功能应用于不同的列
【发布时间】:2014-12-13 13:47:15
【问题描述】:

当使用df.mean() 时,我得到一个结果,其中给出了每列的平均值。现在假设我想要第一列的平均值和第二列的总和。有没有办法做到这一点?我不想拆卸和重新组装DataFrame

我最初的想法是按照pandas.groupby.agg() 的方式做一些事情,如下所示:

df = pd.DataFrame(np.random.random((10,2)), columns=['A','B'])
df.apply({'A':np.mean, 'B':np.sum}, axis=0)

Traceback (most recent call last):

  File "<ipython-input-81-265d3e797682>", line 1, in <module>
    df.apply({'A':np.mean, 'B':np.sum}, axis=0)

  File "C:\Users\Patrick\Anaconda\lib\site-packages\pandas\core\frame.py", line 3471, in apply
    return self._apply_standard(f, axis, reduce=reduce)

  File "C:\Users\Patrick\Anaconda\lib\site-packages\pandas\core\frame.py", line 3560, in _apply_standard
    results[i] = func(v)

TypeError: ("'dict' object is not callable", u'occurred at index A')

但这显然行不通。似乎传递 dict 是一种直观的方式,但还有另一种方式(同样无需拆卸和重新组装DataFrame)?

【问题讨论】:

    标签: python pandas aggregate


    【解决方案1】:

    你可以试试闭包:

    def multi_func(functions):
        def f(col):
            return functions[col.name](col)
        return f
    
    df = pd.DataFrame(np.random.random((10, 2)), columns=['A', 'B'])
    result = df.apply(multi_func({'A': np.mean, 'B': np.sum}))
    

    【讨论】:

    • 这其实很不错。我的解决方法是将一列插入到数据框中,对该列执行 groupby 然后将 dict 传递给聚合方法。
    • 谢谢!我注意到,如果 DataFrame 中的列多于函数 dict 中的键,这将失败。 @bill-letson 你也看到了吗?
    • 一个完整的实现应该包括一个 try KeyError 子句,它返回一个标识函数: lambda x : x
    • @phil_20686 您可以通过将functions[col.name](col) 替换为functions.get(col.name, lambda x: x)(col) 来做到这一点
    【解决方案2】:

    我认为您可以使用带有字典作为参数的agg 方法。例如:

    df = pd.DataFrame({'A': [0, 1, 2], 'B': [3, 4, 5]})
    
    df =
    A   B
    0   0   3
    1   1   4
    2   2   5
    
    df.agg({'A': 'mean', 'B': sum})
    
    A     1.0
    B    12.0
    dtype: float64
    

    【讨论】:

      【解决方案3】:

      我自己刚刚遇到这种情况并想出了以下内容:

      In [1]: import pandas as pd
      
      In [2]: df = pd.DataFrame([['one', 'two'], ['three', 'four'], ['five', 'six']], 
         ...:                   columns=['A', 'B'])
      
      In [3]: df
      Out[3]: 
             A     B
      0    one   two
      1  three  four
      2   five   six
      
      In [4]: converters = {'A': lambda x: x[:1], 'B': lambda x: x.replace('o', '')}
      
      In [5]: new = pd.DataFrame.from_dict({col: series.apply(converters[col]) 
         ...:                               if col in converters else series
         ...:                               for col, series in df.iteritems()})
      
      In [6]: new
      Out[6]: 
         A    B
      0  o   tw
      1  t  fur
      2  f  six
      

      【讨论】:

        猜你喜欢
        • 2017-04-03
        • 1970-01-01
        • 2016-01-17
        • 2014-04-11
        • 1970-01-01
        • 1970-01-01
        • 2013-02-28
        • 1970-01-01
        • 2018-08-29
        相关资源
        最近更新 更多