如何在pandas中使用多个列映射函数?

ash*_*gal 11 python pandas

我已经检查了地图,应用,mapapply和组合,但似乎无法找到一种简单的方法来执行以下操作:

我有一个包含10列的数据框.我需要将其中的三个传递给一个带有标量并返回标量的函数...

some_func(int a, int b, int c) returns int d
Run Code Online (Sandbox Code Playgroud)

我想应用它并在数据框中创建一个带有结果的新列.

df['d'] = some_func(a = df['a'], b = df['b'], c = df['c'])
Run Code Online (Sandbox Code Playgroud)

我发现的所有解决方案似乎都建议重写some_func以使用Series而不是标量,但这是不可能的,因为它是另一个包的一部分.我如何优雅地完成上述工作?

tsh*_*wen 17

使用pd.DataFrame.apply(),如下:

df['d'] = df.apply(lambda x: some_func(a = x['a'], b = x['b'], c = x['c']), axis=1)
Run Code Online (Sandbox Code Playgroud)

注意:当@ashishsingal询问有关列时,axis应该为参数提供值1,因为默认值为0(如文档中所示并在下面复制).

axis:{0或'index',1或'columns'},默认为0

  • 0或'index':将函数应用于每列
  • 或'columns':将函数应用于每一行


Tob*_*tty 7

对于这样一个老问题,它的价值是什么?我发现将函数参数压缩成元组,然后将该函数作为列表推导式应用比使用df.apply. 例如:

import pandas as pd

# Setup:
df = pd.DataFrame(np.random.rand(10000, 3), columns=list("abc"))
def some_func(a, b, c):
    return a*b*c

# Using apply:
%timeit df['d'] = df.apply(lambda x: some_func(a = x['a'], b = x['b'], c = x['c']), axis=1)
Run Code Online (Sandbox Code Playgroud)

每个循环 222 ms ± 63.8 ms(7 次运行的平均值 ± 标准偏差,每次 1 次循环)

# Using tuples + list comprehension:
%timeit df["d"] = [some_func(*a) for a in tuple(zip(df["a"], df["b"], df["c"]))]
Run Code Online (Sandbox Code Playgroud)

每个循环 8.07 ms ± 640 µs(7 次运行的平均值 ± 标准偏差,每次 100 次循环)

  • @ML_Passion,您好,是的,只要您将 `some_func` 更改为返回 2 个值而不是 1,它就会完全按照您的说法工作。实际上,`apply` 方法不适用于一次添加多列的用例,它需要多次应用,使其变得更慢,所以这是此方法的另一个胜利。 (2认同)

And*_*eno 7

我使用的映射与列表理解一样快(比应用快得多):

\n
df['d'] = list(map(some_func, df['a'], df['b'], df['c']))\n
Run Code Online (Sandbox Code Playgroud)\n

我的机器上的示例:

\n
import pandas as pd\n\n# Setup:\ndf = pd.DataFrame(np.random.rand(10000, 3), columns=list("abc"))\ndef some_func(a, b, c):\n    return a*b*c\n\n# Using apply:\n%timeit df['d'] = df.apply(lambda x: some_func(a = x['a'], \nb = x['b'], c = x['c']), axis=1)\n
Run Code Online (Sandbox Code Playgroud)\n

130 ms \xc2\xb1 每个循环 1.11 ms(平均 \xc2\xb1 标准偏差 7 次运行,每次 10 个循环)

\n
%timeit df['d'] = list(map(some_func, df['a'], df['b'], df['c']))\n
Run Code Online (Sandbox Code Playgroud)\n

每个循环 3.91 ms \xc2\xb1 22.9 \xc2\xb5s(平均 7 次运行的 \xc2\xb1 标准偏差,每次 100 个循环)

\n