应用具有多个参数的函数以创建新的pandas列


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)

但是,当函数需要多个参数时,我无法弄清楚该怎么做。例如,如何通过将A列和B列传递给下面的函数来创建新列?

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

Answers:


136

另外,您可以使用numpy基础函数:

>>> 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不起作用。原因是,其中一列属于type pandas._libs.tslibs.timestamps.Timestampnumpy.datetime64通过向量化它变成了type 。这两种类型不可互换,从而导致功能无法正常运行。有什么建议吗?(除了.apply显然要避免这样做以外)
ElRudi

很好的解决方案!以防万一有人想知道向量化是否可以很好地并且对于字符串比较功能也非常快。
infiniteloop

227

如果可以重写函数,则可以使用@greenAfrican示例。但是,如果您不想重写函数,可以将其包装到apply内部的匿名函数中,如下所示:

>>> 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
这是一个很好的技巧,它使列引用靠近apply调用(实际上在其中)。我使用了这个技巧和提供的多列输出技巧@toto_tico来生成3列输入,4列输出功能!很棒!
RufusVS

7
哇,看来您是唯一一个不专注于OP的最小示例,却解决了整个问题的人,谢谢,正是我所需要的!:)
马特

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
我想知道如何用一个应用生成多个列!我将此与@Roman Pekar的答案一起使用,以生成3列输入,4列输出功能!很棒!
RufusVS

14

另一种dict风格的干净语法:

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

要么,

df["new_column"] = df["A"] * df["B"]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.