2016-03-29 21 views
2

IGroß Datenrahmen Spalte Multiplikation

in>> all_data.shape 
out>> (228714, 436) 

Was einen sehr großen Datenrahmen habe ich effciently zu tun ist multiplizieren viele der Spalten zusammen. Ich begann mit einer for-Schleife und die Liste der Spalten - die effcient Weise, die ich gefunden habe, ist

from itertools import combinations 
newcolnames=list(all_data.columns.values) 
newcolnames=newcolnames[0:87] 
#make cross products (the columns I want to operate on are the first 87) 
for c1, c2 in combinations(newcolnames, 2): 
    all_data['{0}*{1}'.format(c1,c2)] = all_data[c1] * all_data[c2] 

Das Problem, wie man vermuten kann, ist ich habe 87 Säulen, die in der Größenordnung von 3800 neuen Spalten geben würde (ja das habe ich beabsichtigt). Sowohl mein jupyter Notebook als auch die ipython-Shell ersticken an dieser Berechnung. Ich muss einen besseren Weg finden, diese Multiplikation durchzuführen.

Gibt es eine effizientere Möglichkeit zu vektorisieren und/oder zu verarbeiten? Vielleicht benutze ich ein numpy Array (mein Datenframe wurde verarbeitet und enthält jetzt nur Zahlen und NANs, es begann mit kategorialen Variablen).

Antwort

0

können Sie versuchen, die df.eval() Methode:

for c1, c2 in combinations(newcolnames, 2): 
    all_data['{0}*{1}'.format(c1,c2)] = all_data.eval('{} * {}'.format(c1, c2)) 
+0

Das ist nicht viel zu ändern schien - es wird noch mehrere Stunden und alle meine Systemspeicher (8 GB) nehmen. Es ist sehr seltsam, wenn ich den Prozess in Stücke (wie sagen wir die ersten 5 Spalten) brechen. Wenn ich weitermache, verlangsamt sich der Prozess, obwohl ich weniger Berechnungen durchführen muss. Die erste "Runde" für Spalte 1 sollte 86 Spaltenberechnungen machen, während etwa 40 I bis 40 Spalten sein sollte. In der Tat lief der erste Teil in Sekunden, während es mehr als eine Stunde dauerte, die Spalten 40-45 zu machen. Einfach nur komisch. – RDS

+1

Ich fürchte, ein Datenrahmen von 228714 Zeilen und 3800 + Spalten wird Ihre 8 GB Speicher verbrauchen, angenommen 16 Bit doppelt in Ihrem df, 228714 * 3800 * 16/1024 ** 3 = 12,95 GB – cncggvg

1

Wie Sie NumPy in der Frage erwähnt haben, das könnte ein gangbarer Weg sein, hier speziell, weil man im 2D-Raum von NumPy statt 1D arbeiten möchte Säulenbearbeitung mit Pandas. Um zu beginnen, können Sie den Datenrahmen zu einem NumPy Array mit einem Aufruf an np.array, wie so konvertieren -

arr = np.array(df) # df is the input dataframe 

Jetzt können Sie die paarweise Kombinationen der Spalten-IDs und dann Index in die Spalten und führen Spalte -wise Multiplikationen und all dies würde in einer vektorisierten Weise erfolgen, wie so -

idx = np.array(list(combinations(newcolnames, 2))) 
out = arr[:,idx[:,0]]*arr[:,idx[:,1]] 

Probelauf -

In [117]: arr = np.random.randint(0,9,(4,8)) 
    ...: newcolnames = [1,4,5,7] 
    ...: for c1, c2 in combinations(newcolnames, 2): 
    ...:  print arr[:,c1] * arr[:,c2] 
    ...:  
[16 2 4 56] 
[64 2 6 16] 
[56 3 0 24] 
[16 4 24 14] 
[14 6 0 21] 
[56 6 0 6] 

In [118]: idx = np.array(list(combinations(newcolnames, 2))) 
    ...: out = arr[:,idx[:,0]]*arr[:,idx[:,1]] 
    ...: 

In [119]: out.T 
Out[119]: 
array([[16, 2, 4, 56], 
     [64, 2, 6, 16], 
     [56, 3, 0, 24], 
     [16, 4, 24, 14], 
     [14, 6, 0, 21], 
     [56, 6, 0, 6]]) 

Schließlich Sie t erstellen er Ausgangsdatenrahmen mit propers Spaltenüberschriften (falls erforderlich), wie so -

>>> headers = ['{0}*{1}'.format(idx[i,0],idx[i,1]) for i in range(len(idx))] 
>>> out_df = pd.DataFrame(out,columns = headers) 
>>> df 
    0 1 2 3 4 5 6 7 
0 6 1 1 6 1 5 6 3 
1 6 1 2 6 4 3 8 8 
2 5 1 4 1 0 6 5 3 
3 7 2 0 3 7 0 5 7 
>>> out_df 
    1*4 1*5 1*7 4*5 4*7 5*7 
0 1 5 3 5 3 15 
1 4 3 8 12 32 24 
2 0 6 3 0 0 18 
3 14 0 14 0 49 0 
Verwandte Themen