【问题标题】:While using pandas apply() how to return the name of the function in a column?使用 pandas apply() 时如何在列中返回函数的名称?
【发布时间】:2018-12-18 16:44:37
【问题描述】:

假设以下 pandas 数据框:

A
1
1
2
4
10

还有以下功能:

def sum(A):
    return 2 + A

我将 sum 函数应用于 pandas 数据框,如下所示:

df['sum'] = df['A'].apply(sum)

如何在另一列中返回函数的名称?例如,预期的输出如下所示:

A sum func_name
1   3   sum
1   3   sum
2   4   sum
4   6   sum
10  12  sum

原因是我想跟踪每个值所应用的内容。

【问题讨论】:

  • 嗯,它已经在您的列名中了。如果你迭代函数,你可以得到它们的名字:for func in funcs: df[func.__name__] = df['A'].apply(func)
  • 拜托,拜托,避免覆盖像sum这样的python内置函数
  • 如果函数是匿名的会发生什么? (df['A'].apply(lambda a: 2 + a))
  • @ernest_k,这正是应该首选基于显式字典的映射的原因。试图在我的回答中解释这一点。

标签: python python-3.x pandas


【解决方案1】:

如果你想获取函数名,另一个选项是使用f.__name__。示例:

def mysum(X):
    return 2 + X

def foo(X, function):
    return pd.Series({
        function.__name__: function(X), 'func_name': function.__name__})

df.join(df.A.apply(foo, function=mysum))

    A  mysum func_name
0   1      3     mysum
1   1      3     mysum
2   2      4     mysum
3   4      6     mysum
4  10     12     mysum

def myprod(X):
    return 2 * X    

df.join(df.A.apply(foo, function=myprod))

    A  myprod func_name
0   1       2    myprod
1   1       2    myprod
2   2       4    myprod
3   4       8    myprod
4  10      20    myprod

我假设您已经熟悉以这种方式使用apply 的陷阱。我在假设你的函数是更复杂的东西的替代品的情况下写了这个。但总的来说,您应该尽可能地尝试矢量化。


如果您想要更灵活地命名输出列,可以添加关键字参数name

def foo(X, function, name=None):
    name = name if name else function.__name__
    return pd.Series({
        name: function(X), 'func_name': function.__name__})

df.join(df.A.apply(foo, function=mysum, name='sum'))

    A  sum func_name
0   1    3     mysum
1   1    3     mysum
2   2    4     mysum
3   4    6     mysum
4  10   12     mysum

【讨论】:

    【解决方案2】:

    您可以查看inspect

    import inspect
    
    def SUM(A):
        return pd.Series([2 + A,  inspect.stack()[0][3]],index=['value','func_name'])
    df['A'].apply(SUM)
    Out[5]: 
       value func_name
    0      3       SUM
    1      3       SUM
    2      4       SUM
    3      6       SUM
    4     12       SUM
    

    【讨论】:

      【解决方案3】:

      如果您需要使用函数的名称,请使用字典作为调度程序。这是干净和可靠的。它避免了隐藏内置的sum 函数,即not recommended

      def summer(A):
          return 2 + A
      
      def apply_func(s, func):
          d = {'sum': summer}
          return s.apply(d[func]), func
      
      df['sum'], df['func_name'] = apply_func(df['A'], 'sum')
      
      print(df)
      
          A  sum func_name
      0   1    3       sum
      1   1    3       sum
      2   2    4       sum
      3   4    6       sum
      4  10   12       sum
      

      对于 Pandas,您应该避免 pd.Series.apply,因为这代表了一个低效的 Python 级循环。在这种情况下,您的函数可以通过重新定义 apply_func 来简单地向量化:

      def apply_func(s, func):
          d = {'sum': summer}
          return d[func](s), func
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-28
        • 2021-03-16
        • 2019-08-22
        • 1970-01-01
        • 2022-01-16
        相关资源
        最近更新 更多