2013-08-27 50 views
5

Hãy nói rằng khung dữ liệu của tôi có chứa những dữ liệu này:làm thế nào để tính toán một cột mới dựa trên các giá trị của các cột khác trong gấu trúc - python

>>> df = pd.DataFrame({'a':['l1','l2','l1','l2','l1','l2'], 
         'b':['1','2','2','1','2','2']}) 
>>> df 
    a  b 
0 l1  1 
1 l2  2 
2 l1  2 
3 l2  1 
4 l1  2 
5 l2  2 

l1 phải tương ứng với 1 trong khi l2 phải tương ứng với 2. Tôi muốn tạo cột mới 'c' sao cho, đối với mỗi hàng, c = 1 nếu a = l1b = 1 (hoặc a = l2b = 2). Nếu a = l1b = 2 (hoặc a = l2b = 1) thì c = 0.

Khung dữ liệu kết quả sẽ giống như thế này:

a   b c 
0 l1  1 1 
1 l2  2 1 
2 l1  2 0 
3 l2  1 0 
4 l1  2 0 
5 l2  2 1 

khung dữ liệu của tôi là rất lớn vì vậy tôi thực sự tìm kiếm những cách hiệu quả nhất để làm điều này bằng gấu trúc.

Trả lời

8
df = pd.DataFrame({'a': numpy.random.choice(['l1', 'l2'], 1000000), 
        'b': numpy.random.choice(['1', '2'], 1000000)}) 

Một giải pháp nhanh chóng giả sử chỉ có hai giá trị khác biệt:

%timeit df['c'] = ((df.a == 'l1') == (df.b == '1')).astype(int) 

10 vòng, tốt nhất là 3: 178 ms mỗi vòng lặp

@Viktor Kerkes:

%timeit df['c'] = (df.a.str[-1] == df.b).astype(int) 

1 vòng, tốt nhất là 3: 412 ms mỗi vòng lặp

@ user1470788:

%timeit df['c'] = (((df['a'] == 'l1')&(df['b']=='1'))|((df['a'] == 'l2')&(df['b']=='2'))).astype(int) 

1 vòng, tốt nhất là 3: 363 ms mỗi vòng lặp

@herrfz

%timeit df['c'] = (df.a.apply(lambda x: x[1:])==df.b).astype(int) 

1 vòng, tốt nhất là 3: 387 ms trên mỗi vòng

+1

Thú vị, tuy nhiên giải pháp của bạn ít tổng quát hơn đáng kể. Điều thú vị ở đây là phương pháp 'str [1]' xấu như thế nào so với lambda đơn giản. –

+0

Bạn không kiểm tra khi nào '(df.a == 'l2') == (df.b == '2')'. –

+0

@StevenRumbalski Tôi cho rằng đầu vào ví dụ đã hoàn thành và 'a' chỉ có giá trị' l1' hoặc 'l2' và' b' chỉ ''1'' hoặc'' 2''. Nếu 'a! = 'L1'', nó phải là'' l2''. – chlunde

2

df['c'] = (df.a.apply(lambda x: x[1:])==df.b).astype(int)

6

Bạn cũng có thể sử dụng các phương pháp chuỗi.

df['c'] = (df.a.str[-1] == df.b).astype(int) 
0

Bạn chỉ có thể sử dụng toán tử logic. Tôi không chắc chắn lý do tại sao bạn đang sử dụng chuỗi 1 và 2 thay vì ints, nhưng đây là một giải pháp. Astype ở cuối chuyển đổi nó từ boolean thành 0 và 1's.

df['c'] = (((df['a'] == 'l1')&(df['b']=='1'))|((df['a'] == 'l2')&(df['b']=='2'))).astype(int)