我已经检查了地图,应用,mapapply和合并,但似乎无法找到一种简单的方法来执行以下操作:
我有一个包含10列的数据框。我需要将其中的三个传递给一个带有标量并返回标量的函数...
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以使用Series而不是标量,但这是不可能的,因为它是另一个包的一部分。我如何优雅地完成上述工作?
答案 0 :(得分:17)
使用pd.DataFrame.apply()
,如下所示:
df['d'] = df.apply(lambda x: some_func(a = x['a'], b = x['b'], c = x['c']), axis=1)
注意:当@ashishsingal询问列时,axis
参数应提供值1,默认值为0(如documentation中所示,并在下面复制)。
轴:{0或'索引',1或'列'},默认为0
- 0或'index':将函数应用于每列
- 或'columns':将函数应用于每一行
答案 1 :(得分:4)
我正在使用以下内容:
df['d'] = df.apply(lambda x: some_func(a = x['a'], b = x['b'], c = x['c']))
似乎运作良好,但如果其他人有更好的解决方案,请告诉我。
答案 2 :(得分:1)
在这样一个古老的问题上有什么价值?我发现将函数参数压缩到元组中,然后将其用作列表推导要比使用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 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"]))]
每个循环8.07 ms±640 µs(平均±标准偏差,共运行7次,每个循环100个)
答案 3 :(得分:0)
如果它是一个非常简单的函数,例如基于简单算术的函数,则有可能对其进行矢量化处理。例如,可以直接从列中进行线性组合:
df["d"] = w1*df["a"] + w2*df["b"] + w3*["c"]
其中w1,w2,w3是标量权重。