2015-07-08 11 views
5

Ich versuche eine Datenrahmenumwandlung durchzuführen, die ich nicht lösen kann. Ich habe mehrere Ansätze aus stackoverflow und der Pandas-Dokumentation ausprobiert: apply, apply (lambda: ...), pivots und joins. Zu viele Versuche, hier aufzulisten, aber nicht sicher, welcher Ansatz der beste ist oder ob ich vielleicht den richtigen Ansatz mit der falschen Syntax versucht habe.Python - Pandas - Dataframe: Reihenspezifischer bedingter Spaltenversatz

Grundsätzlich habe ich einen Datenrahmen, und ich muss 1) die Spalten versetzen, 2) die Anzahl der Spalten, um Offset durch variiert und hängt von einer Variablen im Datenrahmen, 3) Spalten am Ende des Datenrahmens erstellen wo benötigt, um den Offset unterzubringen, und 4) platziere Nullen in den neu erzeugten Intervallen.

df1 = pd.DataFrame({'first' : ['John', 'Mary', 'Larry', 'jerry'], '1' : [5.5, 6.0,10,20], '2' : [100, 200, 300, 400], '3' : [150, 100, 240, 110], 'offset' : ([1,0,2,1])}) 
goal_df = pd.DataFrame({'first' : ['John', 'Mary', 'Larry', 'jerry'], '1' : [0.0, 6.0, 0.0, 0], '2' : [5.5, 200, 0.0, 20], '3' : [100, 100, 10, 400], '4' : [150, 0.0, 300, 110], '5' : [0.0, 0.0, 240, 0.0]}) 

df1 
1   2  3 first  offset 
5.5  100  150 John  1 
6.0  200  100 Mary  0 
10.0  300  240 Larry  2 
20.0  400  110 jerry  1 


goal_df 
1  2 3 4 5 first 
0 5.5 100 150 0 John 
6 200.0 100 0 0 Mary 
0 0.0 10 300 240 Larry 
0 20.0 400 110 0 jerry 

Dieser Datensatz enthält c. 500 Reihen und c. 120 Spalten. Der Betrag des Versatzes wird sehr zwischen 0-12 liegen. Ich dachte darüber nach, dies mit Basis-Python-Funktionen zu tun, aber ich fand auch, dass es schwierig war und der Zeitkonsument durch das Programm den ultimativen Zweck besiegen würde, nämlich einige Aufgaben in Microsoft Excel zu erledigen.

Ich beschwere mich sehr darüber, wie Excel für große Aufgaben wie diese unterlegen ist, aber es scheint so weit, dass die aktuelle Tabellenkalkulation offset() Funktion in Excel dies auf eine sehr einfache Art und Weise tut, aber mit Tausenden von Formeln, ist sehr langsam. Ich habe meinen Arbeitsplatz auf die Vorteile von Python gegenüber Excel verkauft, und dies ist meine erste echte Testversion, daher ist Geschwindigkeit für mich sehr wichtig, weil ich versuche, meine Kollegen davon zu überzeugen, dass Python diese Tabelle viel schneller verschlingen kann als das aktuelle Excel Datei mit einer Dateigröße von 96 MB.

Ich kam ziemlich nah mit der Funktion melt() und nahm dann die früheren Spaltennummern und fügte den Offset zu ihnen hinzu. Allerdings hatte ich viele Probleme, den Datenrahmen mit Pivot zu reformieren. Kein Glück mit bewerben oder bewerben (Lambda)!

Danke für jede Hilfe, die jeder geben kann!

Antwort

3

Dies ist nicht besonders elegant oder prägnant, aber sollte den Trick tun. Ich finde es ein wenig einfacher Spalten in numpy herum zu mischen (sollte auch ein bisschen schneller sein), also konvertiere ich zuerst von einem Datenrahmen in ein Array.

Hier ist der Schlüsselcode, der einfach jede Zeile um den Offset verschiebt.

for i, j in enumerate(offset): 
    arr2[i,j:3+j] = arr[i] 

array([[ 0. , 5.5, 100. , 150. , 0. ], 
     [ 6. , 200. , 100. , 0. , 0. ], 
     [ 0. , 0. , 10. , 300. , 240. ], 
     [ 0. , 20. , 400. , 110. , 0. ]]) 

Darüber hinaus ist es nur ein wenig Handarbeit Platz für die Spalten hinzufügen und sie in der richtigen Reihenfolge gebracht.

df2 = df1.copy() 
last_column = 6 
for i in map(str,range(3,last_column)): 
    df2[i] = 0 
df2 = df2[ map(str,range(1,last_column))+['first','offset']] 

Dann laden arr2 in df2.

df2.loc[:,'1':'5'] = arr2 

    1  2 3 4 5 first offset 
0 0 5.5 100 150 0 John  1 
1 6 200.0 100 0 0 Mary  0 
2 0 0.0 10 300 240 Larry  2 
3 0 20.0 400 110 0 jerry  1 
+0

Vielen Dank für einen Blick. Ich probiere deine Lösung aus, also habe ich wenigstens etwas, das funktioniert. In der Zwischenzeit werde ich versuchen, diesen einen Weg zu entwickeln, den Datenrahmen zu schmelzen und die Spaltennummern zu mutieren (alte Spaltennummer + Offset). Das einzige Problem ist, dass wenn ich den Datenrahmen "unmelt", der Pivot alles komplett vermasselt. – nordicray

+0

@nordicray OK, wenn du den Schmelz/Pivot-Weg bevorzugst, möchtest du vielleicht das, was du versucht hast, posten und sehen, ob es jemand reparieren oder verbessern kann. – JohnE

+0

Danke @JohnE. Der Grund, warum ich es nicht gepostet habe, ist, dass ich jedes Mal, wenn ich dachte, dass ich in der Nähe bin, merke, wie weit ich eigentlich entfernt war. Ich denke, dass ich mehr Nachforschungen anstellen muss und wirklich darauf achten muss, wie die Multiindizierung für Datenrahmen in Pandas funktioniert, bevor ich eine rationellere Version davon ausprobiere. Ich denke auch, dass Hilfe in einigen anderen Bereichen, an denen ich arbeite, ist. – nordicray