2016-04-06 14 views
1

Ich arbeite mit großen Datasets, so dass pandas group und groupby Funktionen eine lange Zeit brauchen/zu viel Speicher verbrauchen. Ich habe gehört, dass einige Leute sagen, Groupby kann langsam sein, aber ich habe Probleme, eine bessere Lösung zu finden.Erstellen einer neuen Spalte in Pandas Datenrahmen mit einer Liste von Werten aus einer anderen Spalte ohne "groupby"

Wenn mein Datenrahmen hat zwei Spalten ähnlich wie:

df = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]}) 

a  b  
1  1  
2  1  
2  1  
4  1  

Ich mag eine Liste von Werten zurück, die in einer anderen Spalte auf einen Wert entsprechen:

a  b  list_of_b 
1  1  [1] 
2  1  [1,1] 
2  1  [1,1] 
4  1  [1] 

ich derzeit verwenden:

df_group = df.groupby('a') 
df['list_of_b'] = df.apply(lambda row: df_group.get_group(row['a'])['b'].tolist(), axis=1) 

Der obige Code funktioniert für kleine Dinge, aber nicht für große Datenrahmen (df> 1.000.000 Zeilen) Hat jemand ha Einen schnelleren Weg, dies zu tun?

+0

eine Liste der Werte zu schaffen, ist aufgrund Pandas problematisch wollen dies auf eine Serie konvertieren und auf Index ausrichten, könnten Sie versuchen 'df [‚list_of_b‘] = df ['a']. map (df.groupby ('a') ['b']. apply (Liste)) 'für die Geschwindigkeit – EdChum

Antwort

0

Kürzeste Lösung, die ich mir vorstellen kann:

df = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]}) 
df.join(pd.Series(df.groupby(by='a').apply(lambda x: list(x.b)), name="list_of_b"), on='a') 

    a b list_of_b 
0 1 1  [1] 
1 2 1 [1, 1] 
2 2 1 [1, 1] 
3 4 1  [1] 
0

Auf einer 4K-Reihe df ich folgende erhalten:

In [29]: 
df_group = df.groupby('a') 
​ 
%timeit df.apply(lambda row: df_group.get_group(row['a'])['b'].tolist(), axis=1) 
%timeit df['a'].map(df.groupby('a')['b'].apply(list)) 

1 loops, best of 3: 4.37 s per loop 
100 loops, best of 3: 4.21 ms per loop 
0

einfach die Gruppierung zu tun und dann Verbinden wieder auf den ursprünglichen Datenrahmen scheint schneller ziemlich viel zu sein:

def make_lists(df): 
    g = df.groupby('a') 
    def list_of_b(x): 
     return x.b.tolist() 
    return df.set_index('a').join(
     pd.DataFrame(g.apply(list_of_b), 
        columns=['list_of_b']), 
     rsuffix='_').reset_index() 

Dies gibt me 192ms pro Schleife mit 1M Reihen erzeugt wie folgt aus:

df1 = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]}) 
low = 1 
high = 10 
size = 1000000 
df2 = pd.DataFrame({'a':np.random.randint(low,high,size), 
        'b':np.random.randint(low,high,size)}) 

make_lists(df1) 
Out[155]: 
    a b list_of_b 
0 1 1 [1] 
1 2 1 [1, 1] 
2 2 1 [1, 1] 
3 4 1 [1] 
In [156]: 


%%timeit 
make_lists(df2) 
10 loops, best of 3: 192 ms per loop 
Verwandte Themen