2016-08-20 5 views
3

Ich schrieb ursprünglich etwas Code in Python 2.7, aber jetzt wechselte ich zu Python 3.5. Ich möchte numerische Daten aus ein paar Spalten aggregieren und gruppieren nach dem Rest von ihnen oder mindestens einem.groupby python TypeError: unkorrigierbare Typen: tuple() <str()

Hier ist mein erster Datenrahmen "testdf":

testdf 
    PROD_TAG BRAND Market   ('VAL', 'Per1') ('VAL', 'Per2') 
     P_1  A  Modern Trade   4.3   0.155 
     P_2  A  Traditional Trade 5.7   0 
     P_3  B  Modern Trade   10.0   11.2 
     P_3  B  Traditional Trade 8.7   6.3 
     P_4  C  Modern Trade   12.1   12.3 
     P_5  D  Modern Trade   8.0   7.0 

letzte zwei Spaltenüberschriften Tupeln sind (dank Kapitän offensichtlich). Per1 und Per2 stehen für entsprechende Zeiträume. Jetzt

TypeError: unorderable types: tuple() < str() 

:

Ich möchte eine einzige Zeile Code auszuführen, die auf Python zuvor arbeitete 2.7:

testdf=testdf.groupby(['BRAND'])[('VAL','P1'),('VAL','P2')].sum() 

Es ist nicht wegen Tupel Art von Spaltenüberschriften funktioniert und wirft Wenn ich Spaltenüberschriften wie folgt umbenenne:

(Tupel entfernen) Ich werde in der Lage sein, die gleiche Codezeile mit neuen Spaltennamen:

testdf1=testdf.groupby(['BRAND'])['VAL-P1','VAL-P2'].sum() 

und am Ende erhalten:

BRAND  ('VAL', 'Per1') ('VAL', 'Per2') 
    A   10.0    0.155 
    B   18.7    17.5 
    C   12.1    12.3 
    D   8.0    7.0 

meisten wierd, was hier das ist, wenn ich .mean() statt .sum(), min() or .max() verwenden, funktioniert alles einwandfrei, auch mit Tupeln.

Kann mir jemand erklären, wie kann ich solche Aggregationen mit Tupelspalten Namen arbeiten auf Python 3.5 machen?

+0

Ich glaube, das eine sein kann, Fehler. –

+0

Fast ein Jahr verging, ich vergaß dieses Problem und erinnerte mich kürzlich daran, es einfach gemacht zu haben, um dieses Buggy-Pandas-Problem zu beheben, indem ich auf GH-Probleme angesprochen habe. Aber bevor ich aufwuchs, wollte ich prüfen, ob es noch existiert. Und es zeigt sich, dass dieses Problem nicht mehr aktuell ist =) –

Antwort

2

Ich glaube, Sie brauchen groupby.agg zu verwenden und eine Funktion übergeben, die Summe der einzelnen Gruppen wie abgebildet zu aggregieren:

df = pd.DataFrame({'PROD_TAG':["P_1", "P_2", "P_3", "P_3", "P_4", "P_5"], 
        'BRAND':["A", "A", "B", "B", "C", "D"], 
        'Market':["Modern Trade", "Traditional Trade", \ 
        "Modern Trade", "Traditional Trade", "Modern Trade", "Modern Trade"], 
        ('VAL','Per1'):[4.3, 5.7, 10.0, 8.7, 12.1, 8.0], 
        ('VAL','Per2'):[0.155, 0, 11.2, 6.3, 12.3, 7.0]}) 

type(df[('VAL','Per1')].name) 
#<class 'tuple'> 

df.groupby(['BRAND'])[('VAL','Per1'), ('VAL','Per2')].agg(lambda x: x.sum()) 

     (VAL, Per1) (VAL, Per2) 
BRAND       
A    10.0  0.155 
B    18.7  17.500 
C    12.1  12.300 
D    8.0  7.000 

Alternativ wird der Index nicht zurückgesetzt und die Grouper Spalten transformiert werden. So können Sie die TypeError aufgrund der Namenskonflikt der Spalten loswerden [tuple/str].

df.groupby(['BRAND'], as_index=False)[('VAL','Per1'), ('VAL','Per2')].sum() 

    BRAND (VAL, Per1) (VAL, Per2) 
0  A   10.0  0.155 
1  B   18.7  17.500 
2  C   12.1  12.300 
3  D   8.0  7.000 

Aber wenn man die tuple Spalten stringrename, können Sie wie bisher ohne Verwendung agg Funktionen:

df.rename(index=str, columns={('VAL','Per1'): "('VAL','Per1')",  \ 
           ('VAL','Per2'): "('VAL','Per2')"}, inplace=True) 

type(df["('VAL','Per1')"].name) 
#<class 'str'> 

df.groupby(['BRAND'])["('VAL','Per1')","('VAL','Per2')"].sum() 

     ('VAL','Per1') ('VAL','Per2') 
BRAND         
A    10.0   0.155 
B    18.7   17.500 
C    12.1   12.300 
D     8.0   7.000 

Hinweis: in Python 3.5 Getestet

+1

Hallo Mann, vielen Dank für deine Antwort, es funktioniert wirklich. Aber ich verstehe immer noch nicht, warum Python etwas "vergleicht", ich meine tuple()

+0

Das liegt daran, dass Sie Spaltenbeschriftungen verschiedener Typen gruppieren (* eins ist vom Str-Typ und das andere ein Tupel *) und ''as_index = True' standardmäßig in' groupby' verwendet, das Objekt mit Gruppenbezeichnungen als Index zurückgibt. Als Ergebnis vergleichen Sie grundsätzlich zwei verschiedene Typen, die zum 'TypeError' führen. Daher ist es üblich, die Spaltenbeschriftungen in "str" ​​zu ändern, damit diese fehlerhaften Fälle vermieden werden können. –

+0

Yep, ich habe den Punkt, dass Python vergleicht "zwei verschiedene Arten, die zu TypeError führt". Aber ich verstehe nicht, warum es _column Namen _... vergleicht es ist eine einfache Aggregation von Marken zu summieren, was mit was zu vergleichen? –

Verwandte Themen