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

How to map a function using multiple columns in pandas?

我已经查看了 map、apply、mapapply 和 combine,但似乎找不到执行以下操作的简单方法:

我有一个包含 10 列的数据框。我需要将其中三个传递给一个函数,该函数接受标量和 returns 一个标量 ...

some_func(int a, int b, int c) returns int d

我想应用它并使用结果在数据框中创建一个新列。

df['d'] = some_func(a = df['a'], b = df['b'], c = df['c'])

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

我正在使用以下内容:

df['d'] = df.apply(lambda x: some_func(a = x['a'], b = x['b'], c = x['c']))

似乎运行良好,但如果其他人有更好的解决方案,请告诉我。

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

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

注意:如 @ashishsingal asked about columns, the axis argument should be provided with a value of 1, as the default is 0 (as in the documentation 并在下方复制)。

axis : {0 or ‘index’, 1 or ‘columns’}, default 0

  • 0 or ‘index’: apply function to each column
  • or ‘columns’: apply function to each row

如果它是一个非常简单的函数,例如基于简单算术的函数,很可能可以对其进行矢量化。例如,可以直接从列中进行线性组合:

df["d"] = w1*df["a"] + w2*df["b"] + w3*["c"]

其中 w1、w2、w3 是标量权重。

这么老的问题有什么价值;我发现将函数参数压缩成元组,然后将函数作为列表理解来应用比使用 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)

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

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

每个循环 8.07 毫秒 ± 640 微秒(7 次运行的平均值 ± 标准偏差,每次 100 次循环)

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

df['d'] = list(map(some_func, df['a'], df['b'], df['c']))

我机器上的例子:

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)

每个循环 130 毫秒 ± 1.11 毫秒(7 次运行的平均值 ± 标准偏差,每次 10 次循环)

%timeit df['d'] = list(map(some_func, df['a'], df['b'], df['c']))

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