2013-08-27 12 views
5

Powiedzmy moja ramka danych zawiera następujące dane:jak obliczyć nową kolumnę w oparciu o wartości innych kolumn w pand - pyton

>>> 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 powinna odpowiadać 1 natomiast l2 powinna odpowiadać 2. ja chce utworzyć nową kolumnę c „” tak, że dla każdego rzędu c = 1 jeśli a = l1 i b = 1 (lub a = l2 i b = 2). Jeśli a = l1 i b = 2 (lub a = l2 i b = 1) to c = 0.

Powstały ramka danych powinien wyglądać następująco:

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 

Moja ramka danych jest bardzo duża, więc jestem naprawdę szuka najbardziej skuteczny sposób to zrobić przy użyciu pandy.

Odpowiedz

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

szybkie rozwiązanie zakładając tylko dwie różne wartości:

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

10 pętle, najlepiej od 3: 178 ms na pętli

@Viktor Kerkes:

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

1 pętle najlepsze 3: 412 ms na pętli

@ user1470788:

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

1 pętle, najlepiej od 3: 363 ms na pętli

@herrfz

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

1 pętle, najlepiej 3: 387 ms na pętlę

+1

Ciekawe, jednak twoje rozwiązanie jest znacznie mniej ogólne. Interesujące jest to, jak złe 'str [1]' metody w porównaniu do prostej lambda. –

+0

Nie testowałeś, gdy '(df.a == 'l2') == (df.b == '2')'. –

+0

@StevenRumbalski Zakładam, że przykładowe wejście jest kompletne, a 'a' ma tylko wartości' l1' lub 'l2' i' b' tylko '' 1'' lub ''2''. Jeśli 'a! = 'L1'', musi to być'' l2''. – chlunde

2

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

6

Można również użyć metody string.

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

Można po prostu użyć operatorów logicznych. Nie jestem pewien, dlaczego używasz ciągi 1 i 2 zamiast ints, ale tutaj jest rozwiązanie. Atrybut astmy na końcu przekształca go z boolean na 0 i 1's.

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

Powiązane problemy