2016-12-30 70 views
5
import pandas as pd 
data={'col1':[1,3,3,1,2,3,2,2]} 
df=pd.DataFrame(data,columns=['col1']) 
print df 


     col1 
    0  1   
    1  3   
    2  3   
    3  1   
    4  2   
    5  3   
    6  2   
    7  2   

Mam następujące Pandas DataFrame i chcę utworzyć inną kolumnę, która porównuje poprzedni wiersz col1, aby zobaczyć, czy są one równe. Jaki byłby najlepszy sposób na zrobienie tego? Byłoby jak następujące DataFrame. DziękiPorównywanie poprzednich wartości wierszy w Pandas DataFrame

col1 match 
0  1 False  
1  3 False  
2  3 True  
3  1 False  
4  2 False  
5  3 False  
6  2 False  
7  2 True  

Odpowiedz

8

Trzeba eq z shift:

df['match'] = df.col1.eq(df.col1.shift()) 
print (df) 
    col1 match 
0  1 False 
1  3 False 
2  3 True 
3  1 False 
4  2 False 
5  3 False 
6  2 False 
7  2 True 

Albo zamiast eq użycie ==, ale jest to slowier nieco w dużej DataFrame:

df['match'] = df.col1 == df.col1.shift() 
print (df) 
    col1 match 
0  1 False 
1  3 False 
2  3 True 
3  1 False 
4  2 False 
5  3 False 
6  2 False 
7  2 True 

Timings:

import pandas as pd 
data={'col1':[1,3,3,1,2,3,2,2]} 
df=pd.DataFrame(data,columns=['col1']) 
print (df) 
#[80000 rows x 1 columns] 
df = pd.concat([df]*10000).reset_index(drop=True) 

df['match'] = df.col1 == df.col1.shift() 
df['match1'] = df.col1.eq(df.col1.shift()) 
print (df) 

In [208]: %timeit df.col1.eq(df.col1.shift()) 
The slowest run took 4.83 times longer than the fastest. This could mean that an intermediate result is being cached. 
1000 loops, best of 3: 933 µs per loop 

In [209]: %timeit df.col1 == df.col1.shift() 
1000 loops, best of 3: 1 ms per loop 
+0

Można zrobić 'df = pd.concat ([DF] * 10.000 , ignore_index = True) '. – Zero

+1

'==' nie powinno być wolniejsze niż użycie 'eq' w ogóle (na przykład otrzymuję przeciwny wynik, gdy je testuję). –

+0

@ajcr - Dziękuję za komentarz. Testuję go pod oknami więcej razy i jeśli porównuję z skalarem, czasy są takie same, ale jeśli porównać serie 2, 'eq',' ne', 'lt' ... był szybszy jako' == ','! = ', '>' w większym df. Jakie były twoje czasy w większym 'df'? – jezrael

2

1) pandy podejście: Zastosowanie diff:

df['match'] = df['col1'].diff().eq(0) 

2) numpy podejście: Zastosowanie np.ediff1d.

df['match'] = np.ediff1d(df['col1'].values, to_begin=np.NaN) == 0 

Zarówno produkować:

enter image description here

taktowanie: (dla tego samego DF używanego przez @jezrael)

%timeit df.col1.eq(df.col1.shift()) 
1000 loops, best of 3: 731 µs per loop 

%timeit df['col1'].diff().eq(0) 
1000 loops, best of 3: 405 µs per loop 
2

Tutaj się tablice podejście oparte NumPy użyciu slicing to pozwala nam korzystać z widoku s do układu wejściowego dla celów efektywności - Run

def comp_prev(a): 
    return np.concatenate(([False],a[1:] == a[:-1])) 

df['match'] = comp_prev(df.col1.values) 

próbki -

Test
In [48]: df['match'] = comp_prev(df.col1.values) 

In [49]: df 
Out[49]: 
    col1 match 
0  1 False 
1  3 False 
2  3 True 
3  1 False 
4  2 False 
5  3 False 
6  2 False 
7  2 True 

wykonywania -

In [56]: data={'col1':[1,3,3,1,2,3,2,2]} 
    ...: df0=pd.DataFrame(data,columns=['col1']) 
    ...: 

#@jezrael's soln1 
In [57]: df = pd.concat([df0]*10000).reset_index(drop=True) 

In [58]: %timeit df['match'] = df.col1 == df.col1.shift() 
1000 loops, best of 3: 1.53 ms per loop 

#@jezrael's soln2 
In [59]: df = pd.concat([df0]*10000).reset_index(drop=True) 

In [60]: %timeit df['match'] = df.col1.eq(df.col1.shift()) 
1000 loops, best of 3: 1.49 ms per loop 

#@Nickil Maveli's soln1 
In [61]: df = pd.concat([df0]*10000).reset_index(drop=True) 

In [64]: %timeit df['match'] = df['col1'].diff().eq(0) 
1000 loops, best of 3: 1.02 ms per loop 

#@Nickil Maveli's soln2 
In [65]: df = pd.concat([df0]*10000).reset_index(drop=True) 

In [66]: %timeit df['match'] = np.ediff1d(df['col1'].values, to_begin=np.NaN) == 0 
1000 loops, best of 3: 1.52 ms per loop 

# Posted approach in this post 
In [67]: df = pd.concat([df0]*10000).reset_index(drop=True) 

In [68]: %timeit df['match'] = comp_prev(df.col1.values) 
1000 loops, best of 3: 376 µs per loop