对 Pandas 数据框中的每一行只运行一次函数
Posted
技术标签:
【中文标题】对 Pandas 数据框中的每一行只运行一次函数【英文标题】:Run function exactly once for each row in a Pandas dataframe 【发布时间】:2016-08-05 04:50:39 【问题描述】:如果我有一个功能
def do_irreversible_thing(a, b):
print a, b
还有一个数据框,比如说
df = pd.DataFrame([(0, 1), (2, 3), (4, 5)], columns=['a', 'b'])
为 pandas 数据框中的每一行只运行一次函数的最佳方法是什么。 As 在其他 questions 中指出,类似 df.apply pandas 的东西会为第一行调用两次该函数。即使使用 numpy
np.vectorize(do_irreversible_thing)(df.a, df.b)
导致函数在第一行被调用两次,df.T.apply()
或 df.apply(..., axis=1) 也是如此。
有没有比这个显式循环更快或更简洁的方法来调用每一行的函数?
for idx, a, b in df.itertuples():
do_irreversible_thing(a, b)
【问题讨论】:
这听起来像是for
循环的工作。通常没有很好的方法来矢量化副作用。
如果副作用不依赖于每一行的操作,那么它应该是可向量化的
如果您需要运行显式循环,使用zip(df.a, df.b)
或df.itertuples()
可能会获得更好的性能,详见this answer。
【参考方案1】:
我这样做的方式(因为我也不喜欢用 df.itertuples 循环的想法)是:
df.apply(do_irreversible_thing, axis=1)
然后你的函数应该是这样的:
def do_irreversible_thing(x):
print x.a, x.b
这样你应该能够在每一行上运行你的函数。
或
如果你不能修改你的函数,你可以像这样apply
它
df.apply(lambda x: do_irreversible_thing(x[0],x[1]), axis=1)
【讨论】:
【参考方案2】:目前尚不清楚您的函数在做什么,但您可以通过将axis=1
传递给apply
您的函数逐行传递并传递感兴趣的列元素来向每一行传递apply
一个函数:
In [155]:
def foo(a,b):
return a*b
df = pd.DataFrame([(0, 1), (2, 3), (4, 5)], columns=['a', 'b'])
df.apply(lambda x: foo(x['a'], x['b']), axis=1)
Out[155]:
0 0
1 6
2 20
dtype: int64
但是,只要您的函数不依赖于每行上的 df 变异,那么您可以只使用矢量化方法对整个列进行操作:
In [156]:
df['a'] * df['b']
Out[156]:
0 0
1 6
2 20
dtype: int64
原因是因为函数是矢量化的,所以它会更好地扩展,而 apply
只是用于迭代你的 df 的语法糖,所以它本质上是一个 for
循环
【讨论】:
以上是关于对 Pandas 数据框中的每一行只运行一次函数的主要内容,如果未能解决你的问题,请参考以下文章
在Pandas中,我如何将一个函数应用到数据框的某一行,其中行中的每一项都应该作为参数传递给函数?