2016-04-18 14 views
6

ich einen Datenrahmen haben wie diesePassing Spalten in Zeilen auf Python Pandas

id a b c 
101 0 3 0 
102 2 0 5 
103 0 1 4 

und ich möchte so etwas wie dieses

id letter num 
101  a  0 
101  b  3 
101  c  0 
102  a  2 
102  b  0 
102  c  5 
103  a  0 
103  b  1 
103  c  4 

ich die Spaltennamen auf Werte einer Zeile übergeben wollen mit ihre entsprechende ID und das Ergebnis der df.

Ich habe versucht, es in einer Schleife zu machen, jedes Element entsprechend seiner ID einzuführen, aber es ist schrecklich. Gibt es einen einfachen Weg, dies zu tun?

Antwort

6

Sie könnten melt und dann sort:

>>> pd.melt(df, id_vars='id', value_vars=['a','b','c'], 
      var_name='letter', value_name='num').sort_values('id') 
    id letter num 
0 101  a 0 
3 101  b 3 
6 101  c 0 
1 102  a 2 
4 102  b 0 
7 102  c 5 
2 103  a 0 
5 103  b 1 
8 103  c 4 

Wenn Sie den Index zurücksetzen möchten, können Sie immer .reset_index(drop=True) auf dem zurückgegebenen Datenrahmen verwenden.

+0

for-Schleife Diese Lösung ist besser als mein schrecklich, würde ich in _value_vars_ fügen Sie einfach anstelle von [ 'a', 'b', 'c'] -> ** Liste (df.columns [1:]) ** da ich viel mehr Spalten als nur a, b, c hatte –

0

Sie wollen wahrscheinlich etwas entlang der Linien von

df2 = df.stack().reset_index(1) 

tun, dann die Spalten umbenennen

df.stack() produziert eine Serie mit einem Multi-Level-Index:

In [5]: df.stack() 
Out[5]: 
id  
101 a 0 
    b 3 
    c 0 
102 a 2 
    b 0 
    c 5 
103 a 0 
    b 1 
    c 4 
dtype: int64 

Sie möchten diesen mehrstufigen Index dann in eigene Spalten aufteilen. Wenn Sie reset_index(1) verwenden, wird die Spalte id als Index angezeigt. Beachten Sie jedoch, dass die anderen Spalten falsche Namen haben (entsprechend ihren früheren Ebenen im mehrstufigen Index).

In [6]: df.stack().reset_index(1) 
Out[6]: 
    level_1 0 
id    
101  a 0 
101  b 3 
101  c 0 
102  a 2 
102  b 0 
102  c 5 
103  a 0 
103  b 1 
103  c 4 

ihnen So benennen:

In [8]: df2.columns = ['letter', 'num'] 

In [9]: df2 
Out[9]: 
    letter num 
id    
101  a 0 
101  b 3 
101  c 0 
102  a 2 
102  b 0 
102  c 5 
103  a 0 
103  b 1 
103  c 4 
0

Sie ravel verwenden können, um die Werte wieder in eine Spalte neu zu gestalten.

df = pd.DataFrame({'id': [101, 102, 103], 
        'a': [0, 2, 0], 
        'b': [3, 0, 1], 
        'c': [0, 5, 4]})[['id', 'a', 'b', 'c']] 

>>> pd.DataFrame({'letter': df.columns[1:].tolist() * len(df), 
        'num': df.iloc[:, 1:].values.ravel()}) 
    letter num 
0  a 0 
1  b 3 
2  c 0 
3  a 2 
4  b 0 
5  c 5 
6  a 0 
7  b 1 
8  c 4 
Verwandte Themen