2016-04-13 19 views
6

Nếu tôi có một hàmChạy chức năng đúng một lần cho mỗi hàng trong một dataframe Pandas

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

Và một dataframe, nói

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

gì là cách tốt nhất để chạy các chức năng đúng một lần cho mỗi hàng trong một khung dữ liệu gấu trúc. As được chỉ ra trong questions khác, giống như gấu trúc df.apply sẽ gọi hàm hai lần cho hàng đầu tiên. Thậm chí sử dụng NumPy

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

gây chức năng được gọi là hai lần trên hàng đầu tiên, như sẽ df.T.apply() hay df.apply (..., trục = 1).

Có cách nào nhanh hơn hoặc sạch hơn để gọi hàm với mọi hàng hơn vòng lặp rõ ràng này không?

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

Sẽ không 'df.apply (lambda x: do_irreversible_thing (x [ 'a'] , x ['b']), axis = 1) 'hoạt động? bên cạnh ý tưởng là sử dụng các phương pháp vectorised trong chức năng của bạn để nó hoạt động trên toàn bộ các cột quan tâm – EdChum

+0

Điều này nghe giống như một công việc cho một vòng lặp 'for'. Nói chung không phải là cách tốt để vector hóa các tác dụng phụ. – user2357112

+0

Nếu các tác dụng phụ không phụ thuộc vào hoạt động của mỗi hàng thì nó phải được vectorizable – EdChum

Trả lời

2

Đó là chưa rõ ràng những gì chức năng của bạn đang làm nhưng để apply một chức năng để mỗi hàng, bạn có thể làm như vậy bằng cách thông qua axis=1 để apply chức năng của bạn hàng khôn ngoan và thông qua các yếu tố cột quan tâm:

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 

Tuy nhiên, miễn là chức năng của bạn không phụ thuộc vào biến df trên mỗi hàng, bạn chỉ có thể sử dụng phương pháp vectorised để hoạt động trên toàn bộ cột:

In [156]: 
df['a'] * df['b'] 

Out[156]: 
0  0 
1  6 
2 20 
dtype: int64 

Lý do là vì các chức năng được vectorised sau đó nó sẽ mở rộng hơn trong khi apply là đường chỉ là cú pháp cho iterating trên df của bạn để nó là một vòng lặp for yếu

2

Cách tôi làm điều đó (vì tôi cũng không như ý tưởng của Looping với df.itertuples) là:

df.apply(do_irreversible_thing, axis=1) 

và sau đó chức năng của bạn nên được như thế:

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

cách này bạn sẽ có thể chạy chức năng của bạn trên mỗi hàng.

HOẶC

nếu bạn không thể sửa đổi chức năng của bạn, bạn có thể apply nó như thế này

df.apply(lambda x: do_irreversible_thing(x[0],x[1]), axis=1) 
Các vấn đề liên quan