在Pandas数据框中,为每一行仅运行函数一次

20
如果我有一个函数:

def do_irreversible_thing(a, b):
    print a, b

同时,一个数据框,比如说

df = pd.DataFrame([(0, 1), (2, 3), (4, 5)], columns=['a', 'b'])

如何最好地在pandas数据框的每一行上仅运行一次函数?正如其他问题所指出的那样,像df.apply pandas这样的方法会导致第一行的函数被调用两次。其他问题中,甚至使用numpy也是如此。

np.vectorize(do_irreversible_thing)(df.a, df.b)

如果使用df.apply()或者df.T.apply(),将在第一行时导致函数被调用两次。

有没有更快更简洁的方式调用该函数来处理每一行?

   for idx, a, b in df.itertuples():
       do_irreversible_thing(a, b)

这听起来像是一个for循环的工作。通常没有一种好的方法可以向量化副作用。 - user2357112
1
如果副作用不依赖于每行的操作,则应该可向量化。 - EdChum
1
如果您需要运行显式循环,可以使用zip(df.a, df.b)df.itertuples()来获得更好的性能,详见此答案 - root
2个回答

16

我的做法是(因为我也不喜欢使用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)

8

你的函数在做什么不清楚,但是要对每一行应用一个函数,您可以通过传递 axis=1 来使函数逐行进行,并传递感兴趣的列元素给 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只是在您的数据框上进行迭代的语法糖,本质上是一个for循环。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接