在使用pandas apply()时,如何在列中返回函数名称?

时间:2018-12-18 16:44:37

标签: python python-3.x pandas

假定以下熊猫数据框:

A
1
1
2
4
10

以及以下功能:

def sum(A):
    return 2 + A

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

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

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

如果要获取函数名称,则另一个选择是使用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 :(得分:1)

如果需要使用函数名称,请使用字典作为调度程序。这是干净可靠的。这样可以避免隐藏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