我已经检查了地图,应用,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':将函数应用于每一行
对于这样一个老问题,它的价值是什么?我发现将函数参数压缩成元组,然后将该函数作为列表推导式应用比使用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 次循环)
我使用的映射与列表理解一样快(比应用快得多):
\ndf['d'] = list(map(some_func, df['a'], df['b'], df['c']))\nRun Code Online (Sandbox Code Playgroud)\n我的机器上的示例:
\nimport 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)\nRun Code Online (Sandbox Code Playgroud)\n130 ms \xc2\xb1 每个循环 1.11 ms(平均 \xc2\xb1 标准偏差 7 次运行,每次 10 个循环)
\n%timeit df['d'] = list(map(some_func, df['a'], df['b'], df['c']))\nRun Code Online (Sandbox Code Playgroud)\n每个循环 3.91 ms \xc2\xb1 22.9 \xc2\xb5s(平均 7 次运行的 \xc2\xb1 标准偏差,每次 100 个循环)
\n| 归档时间: |
|
| 查看次数: |
16678 次 |
| 最近记录: |