Застосування функції з кількома аргументами для створення нового стовпця панд


165

Я хочу створити новий стовпчик у pandasкадрі даних, застосувавши функцію до двох існуючих стовпців. Після цієї відповіді я зміг створити новий стовпець, коли мені потрібен лише один стовпець як аргумент:

import pandas as pd
df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]})

def fx(x):
    return x * x

print(df)
df['newcolumn'] = df.A.apply(fx)
print(df)

Однак я не можу зрозуміти, як зробити те саме, коли функція вимагає декількох аргументів. Наприклад, як я можу створити новий стовпець, передавши стовпчик А та стовпець В до функції нижче?

def fxy(x, y):
    return x * y

Відповіді:


136

Крім того, ви можете використовувати базову функцію:

>>> import numpy as np
>>> df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]})
>>> df['new_column'] = np.multiply(df['A'], df['B'])
>>> df
    A   B  new_column
0  10  20         200
1  20  30         600
2  30  10         300

або векторизувати довільну функцію в загальному випадку:

>>> def fx(x, y):
...     return x*y
...
>>> df['new_column'] = np.vectorize(fx)(df['A'], df['B'])
>>> df
    A   B  new_column
0  10  20         200
1  20  30         600
2  30  10         300

2
Дякую за відповідь! Мені цікаво, чи це найшвидше рішення?
MV23

6
Векторизована версія за допомогою np.vectorize()надзвичайно швидко. Дякую.
stackoverflowuser2010

Це корисне рішення. Якщо розмір вхідних аргументів функції x і y не дорівнює, ви отримуєте помилку. У цьому випадку рішення @RomanPekar працює без проблем. Я не порівнював продуктивність.
Ehsan Sadr

Я знаю, що це стара відповідь, але: у мене є крайній випадок, в якому np.vectorizeвін не працює. Причина полягає в тому, що один із стовпців має тип pandas._libs.tslibs.timestamps.Timestamp, який перетворюється на тип numpy.datetime64векторизацією. Два типи не є взаємозамінними, через що функція поводиться погано. Будь-які пропозиції щодо цього? (Крім .applyцього, очевидно, цього слід уникати)
ElRudi

Чудове рішення! у випадку, якщо комусь цікаво, що vectorize працює добре і дуже швидко для функцій порівняння рядків.
infiniteloop

227

Ви можете скористатися прикладом @greenAfrican, якщо ви можете переписати свою функцію. Але якщо ви не хочете переписати свою функцію, ви можете перетворити її в анонімну функцію всередині застосувати, наприклад:

>>> def fxy(x, y):
...     return x * y

>>> df['newcolumn'] = df.apply(lambda x: fxy(x['A'], x['B']), axis=1)
>>> df
    A   B  newcolumn
0  10  20        200
1  20  30        600
2  30  10        300

4
Це чудова порада, і він залишає посилання стовпців біля виклику застосувати (фактично в ньому). Я використовував цю підказку, а підказка для виводу з декількох стовпців @toto_tico постачається для створення 3-х стовпців у, 4-колонкової функції! Чудово працює!
RufusVS

7
Нічого собі, здається, ти єдиний, хто не зосереджуєшся на мінімальному прикладі ОП, але вирішуєш всю проблему, дякую саме тому, що мені потрібно! :)
Метт

38

Це вирішує проблему:

df['newcolumn'] = df.A * df.B

Ви також можете зробити:

def fab(row):
  return row['A'] * row['B']

df['newcolumn'] = df.apply(fab, axis=1)

10
Ця відповідь вирішує цей приклад іграшки, і мені буде достатньо, щоб переписати свою фактичну функцію, але вона не стосується того, як застосувати попередньо визначену функцію, не переписуючи її у стовпці посилань.
Майкл

23

Якщо вам потрібно створити кілька стовпців одночасно :

  1. Створіть фрейм даних:

    import pandas as pd
    df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]})
  2. Створіть функцію:

    def fab(row):                                                  
        return row['A'] * row['B'], row['A'] + row['B']
  3. Призначте нові стовпці:

    df['newcolumn'], df['newcolumn2'] = zip(*df.apply(fab, axis=1))

1
Мені було цікаво, як я можу генерувати кілька стовпців за допомогою одного застосунку! Я використав це з відповіддю @ Романа Пекара, щоб створити функцію 3 стовпця, 4 колонки! Чудово працює!
RufusVS

15

Ще один синтаксис чистого стилю dict:

df["new_column"] = df.apply(lambda x: x["A"] * x["B"], axis = 1)

або,

df["new_column"] = df["A"] * df["B"]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.