2013-10-09 8 views
8

Ich versuche, ein Pivot einer Tabelle durchzuführen, die Zeichenfolgen als Ergebnisse enthält.Pandas - Pivot_Table mit nicht-numerischen Werten? (DataError: Keine numerischen Typen zu aggregieren)

import pandas as pd 

df1 = pd.DataFrame({'index' : range(8), 
'variable1' : ["A","A","B","B","A","B","B","A"], 
'variable2' : ["a","b","a","b","a","b","a","b"], 
'variable3' : ["x","x","x","y","y","y","x","y"], 
'result': ["on","off","off","on","on","off","off","on"]}) 

df1.pivot_table(values='result',rows='index',cols=['variable1','variable2','variable3']) 

Aber ich bekomme: DataError: No numeric types to aggregate.

Dies funktioniert wie vorgesehen, wenn ich Ergebniswerte in Zahlen ändern:

df2 = pd.DataFrame({'index' : range(8), 
'variable1' : ["A","A","B","B","A","B","B","A"], 
'variable2' : ["a","b","a","b","a","b","a","b"], 
'variable3' : ["x","x","x","y","y","y","x","y"], 
'result': [1,0,0,1,1,0,0,1]}) 

df2.pivot_table(values='result',rows='index',cols=['variable1','variable2','variable3']) 

Und ich bekomme, was ich brauche:

variable1 A    B  
variable2 a  b  a b 
variable3 x y x y x y 
index        
0   1 NaN NaN NaN NaN NaN 
1   NaN NaN 0 NaN NaN NaN 
2   NaN NaN NaN NaN 0 NaN 
3   NaN NaN NaN NaN NaN 1 
4   NaN 1 NaN NaN NaN NaN 
5   NaN NaN NaN NaN NaN 0 
6   NaN NaN NaN NaN 0 NaN 
7   NaN NaN NaN 1 NaN NaN 

Ich weiß, dass ich die Saiten auf numerische Werte zuordnen kann und dann umkehren die Operation, aber vielleicht gibt es eine elegantere Lösung?

Antwort

23

Meine ursprüngliche Antwort beruhte auf Pandas 0.14.1, und seitdem viele Dinge in der pivot_table Funktion geändert (Zeilen -> Index, cols -> Spalten ...)

Zusätzlich scheint es, dass der ursprüngliche Lambda-Trick, den ich gepostet habe, nicht mehr auf Pandas 0.18 funktioniert. Sie müssen eine reduzierende Funktion bereitstellen (auch wenn es sich um min, max oder mean handelt). Aber auch das schien unpassend - weil wir nicht den Datensatz reduzieren, nur um es umzuwandeln .... So sah ich härter an Entstapelungsunterdrückung ...

import pandas as pd 

df1 = pd.DataFrame({'index' : range(8), 
'variable1' : ["A","A","B","B","A","B","B","A"], 
'variable2' : ["a","b","a","b","a","b","a","b"], 
'variable3' : ["x","x","x","y","y","y","x","y"], 
'result': ["on","off","off","on","on","off","off","on"]}) 

# these are the columns to end up in the multi-index columns. 
unstack_cols = ['variable1', 'variable2', 'variable3'] 

Zuerst setzen auf den Daten einen Index mit dem Index + die Spalten, die Sie stapeln möchten, und dann das Entstapeln mit dem Level arg aufrufen.

df1.set_index(['index'] + unstack_cols).unstack(level=unstack_cols) 

Der resultierende Datenrahmen ist unten.

enter image description here

+0

Schließlich eine Lösung zum Ersetzen der Pivot() ändert sich in Pandas 0.17.1 – camdenl

+0

@RandallGoodwin, ich realisiere diese Frage ist zwei Jahre alt, aber ich bekomme den Fehler "ValueError: Funktion nicht reduziert "Wenn du dein Lambda verwendest, würdest du wissen, warum? – RustyShackleford

+1

Eine andere Idee: Wenn Sie möglicherweise mehrere Werte angezeigt haben, könnten Sie Strings concat, indem Sie Ihre Aggfunc = Lambda x: "" .join ([str (y) für y in x]) – dllahr

2

Ich denke, der beste Kompromiss besteht darin, On/Off durch True/False zu ersetzen, was es Pandas ermöglicht, die Daten besser zu "verstehen" und auf eine intelligente, erwartete Weise zu handeln.

df2 = df1.replace({'on': True, 'off': False}) 

Sie im Wesentlichen in Ihrer Frage eingeräumt. Meine Antwort ist, ich denke nicht, dass es einen besseren Weg gibt, und du solltest sowieso "an"/"aus" ersetzen für was immer als nächstes kommt.

Wie Andy Hayden in den Kommentaren hervorhebt, erhalten Sie eine bessere Leistung, wenn Sie On/Off mit 1/0 ersetzen.

+1

+1, kann jedoch besser sein, so zu verwenden, 1 und 0 als Datenrahmen als Objekt dtype schwebt vielmehr hat :) –

+0

ich nie in Betracht gezogen. Guter Punkt. –

+0

OK, scheint klar genug :) –

Verwandte Themen