При использовании pandas apply () как вернуть имя функции в столбце? - PullRequest
0 голосов
/ 18 декабря 2018

Допустим, следующий кадр данных pandas:

A
1
1
2
4
10

И следующая функция:

def sum(A):
    return 2 + A

Я применяю функцию суммы к кадру данных 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

Причина в том, что я хотел бы отслеживать, что применяется к каждому значению.

Ответы [ 3 ]

0 голосов
/ 18 декабря 2018

Вы можете проверить 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
0 голосов
/ 18 декабря 2018

Если вы хотите получить имя функции, другой вариант использует 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
0 голосов
/ 18 декабря 2018

Если вам нужно использовать имя вашей функции, используйте словарь в качестве диспетчера.Это чисто и надежно.Во избежание необходимости скрывать встроенную функцию sum, которая не рекомендуется .

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

С пандами вы должны избегать pd.Series.apply, поскольку это представляет неэффективный цикл уровня Python.В этом случае ваша функция может быть тривиально векторизована путем переопределения apply_func:

def apply_func(s, func):
    d = {'sum': summer}
    return d[func](s), func
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...