2017-05-29 1 views
1

In Pandas, habe ich einen Datenrahmen, wobei jede Zeile einen Benutzer entspricht, und jede Spalte in einer Variable für diesen Benutzer im Zusammenhang, einschließlich, wie sie eine bestimmte Sache bewertet:eine Reihe von Rating-Spalt in Pandas Verschwenkung

+----------------+--------------------------+----------+----------+ 
|  name  |   email   | rating_a | rating_b | 
+----------------+--------------------------+----------+----------+ 
| Someone  | [email protected]   |  7.8 |  9.9 | 
| Someone Else | [email protected] |  2.4 |  9.2 | 
| Another Person | [email protected] |  3.5 |  7.5 | 
+----------------+--------------------------+----------+----------+ 

ich den Tisch, so dass eine Spalte schwenken wollen, ist die Art der Bewertung (a oder b), ist ein weiterer der Bewertungswert (7.8, 3.5 usw.), und die anderen Spalten sind die gleichen wie oben, wie dies :

+----------------+-------------------------+-------------+--------------+ 
|  name  |   email   | rating_type | rating_value | 
+----------------+-------------------------+-------------+--------------+ 
| Someone  | [email protected]  | a   |   7.8 | 
| Someone  | [email protected]  | b   |   9.9 | 
| Someone Else | [email protected] | a   |   2.4 | 
| Someone Else | [email protected] | b   |   9.2 | 
| Another Person | [email protected] | a   |   3.5 | 
| Another Person | [email protected] | b   |   7.5 | 
+----------------+-------------------------+-------------+--------------+ 

Es scheint, dass die Pandas Methode auf dem richtigen Weg ist, aber ich bin mir nicht ganz sicher, was meine id_vars sind und was meine value_vars in dieser Situation sind. Es scheint auch alle Spalten zu löschen, die nicht in einer dieser zwei Kategorien sind, z.B. Die E-Mail Adresse. Aber ich möchte all diese Informationen behalten.

Wie kann ich das mit Pandas machen?

Antwort

2

können Sie verwenden melt + str.replace Änderungsspaltennamen:

df.columns = df.columns.str.replace('rating_','') 
df = df.melt(id_vars=['name','email'], var_name='rating_type', value_name='rating_value') 
print (df) 
      name      email rating_type rating_value 
0   Someone   [email protected]   a   7.8 
1 Someone Else  [email protected]   a   2.4 
2 Another Person [email protected]   a   3.5 
3   Someone   [email protected]   b   9.9 
4 Someone Else  [email protected]   b   9.2 
5 Another Person [email protected]   b   7.5 

Eine andere Lösung mit set_index + stack + rename_axis + reset_index:

df.columns = df.columns.str.replace('rating_','') 
df = df.set_index(['name','email']) 
     .stack() 
     .rename_axis(['name','email','rating_type']) 
     .reset_index(name='rating_value') 
print (df) 
      name      email rating_type rating_value 
0   Someone   [email protected]   a   7.8 
1   Someone   [email protected]   b   9.9 
2 Someone Else  [email protected]   a   2.4 
3 Someone Else  someone.e[email protected]   b   9.2 
4 Another Person [email protected]   a   3.5 
5 Another Person [email protected]   b   7.5 

Lösung mit melt wenn Reihenfolge der Zeilen ändern müssen:

df.columns = df.columns.str.replace('rating_','') 
df = df.reset_index() \ 
     .melt(id_vars=['index','name','email'], 
      var_name='rating_type', 
      value_name='rating_value')\ 
     .sort_values(['index','rating_type']) \ 
     .drop('index', axis=1) \ 
     .reset_index(drop=True) 
print (df) 
      name      email rating_type rating_value 
0   Someone   [email protected]   a   7.8 
1   Someone   [email protected]   b   9.9 
2 Someone Else  [email protected]   a   2.4 
3 Someone Else  [email protected]   b   9.2 
4 Another Person [email protected]   a   3.5 
5 Another Person [email protected]   b   7.5