2014-12-20 3 views
8

Ich möchte einen Pandas DataFrame, der von einer Pivot-Tabelle abgeleitet ist, in eine Reihendarstellung konvertieren, wie unten gezeigt. DieseFlachen DataFrame mit Multi-Index-Spalten

ist, wo ich bin:

import pandas as pd 
import numpy as np 
df = pd.DataFrame({ 
    'goods': ['a', 'a', 'b', 'b', 'b'], 
    'stock': [5, 10, 30, 40, 10], 
    'category': ['c1', 'c2', 'c1', 'c2', 'c1'], 
    'date': pd.to_datetime(['2014-01-01', '2014-02-01', '2014-01-06', '2014-02-09', '2014-03-09']) 
}) 
# we don't care about year in this example 
df['month'] = df['date'].map(lambda x: x.month) 
piv = df.pivot_table(["stock"], "month", ["goods", "category"], aggfunc="sum") 
piv = piv.reindex(np.arange(piv.index[0], piv.index[-1] + 1)) 
piv = piv.ffill(axis=0) 
piv = piv.fillna(0) 
print piv 

die

stock    
goods  a  b  
category c1 c2 c1 c2 
month      
1   5 0 30 0 
2   5 10 30 40 
3   5 10 10 40 

in Ergebnisse und das ist, wo ich bekommen möchten.

goods category month stock 
    a  c1  1  5 
    a  c1  2  0 
    a  c1  3  0 
    a  c2  1  0 
    a  c2  2 10 
    a  c2  3  0 
    b  c1  1 30 
    b  c1  2  0 
    b  c1  3 10 
    b  c2  1  0 
    b  c2  2 40 
    b  c2  3  0 

Previously, benutzen ich

piv = piv.stack() 
piv = piv.reset_index() 
print piv 

loszuwerden, das Multi-Indizes zu erhalten, aber dies führt zu dem, weil ich jetzt auf zwei Säulen schwenkte (["goods", "category"]):

 month category stock  
goods     a b 
0   1  c1  5 30 
1   1  c2  0 0 
2   2  c1  5 30 
3   2  c2 10 40 
4   3  c1  5 10 
5   3  c2 10 40 

Weiß jemand, wie ich den Multi-Index in der Spalte loswerden kann und das Ergebnis in einen DataFrame des exemplarischen Formats bringen kann?

Antwort

6
>>> piv.unstack().reset_index().drop('level_0', axis=1) 
    goods category month 0 
0  a  c1  1 5 
1  a  c1  2 5 
2  a  c1  3 5 
3  a  c2  1 0 
4  a  c2  2 10 
5  a  c2  3 10 
6  b  c1  1 30 
7  b  c1  2 30 
8  b  c1  3 10 
9  b  c2  1 0 
10  b  c2  2 40 
11  b  c2  3 40 

dann alles, was Sie brauchen, ist 0-stock letzte Spaltennamen zu ändern.

+1

hmmmm, schmelzen (mein Antwort) verliert Monat aus dem Index :( –

+0

Danke. Es funktioniert gut mit meinem Beispiel. Allerdings verstehe ich nicht ganz, warum die Verwendung von 'Stack' zuvor funktioniert und ich sollte jetzt 'Entstapeln' verwenden. – orange

1

Es scheint mir, dass melt (aka unpivot) sehr nahe ist, was Sie tun möchten:

In [11]: pd.melt(piv) 
Out[11]: 
     NaN goods category value 
0 stock  a  c1  5 
1 stock  a  c1  5 
2 stock  a  c1  5 
3 stock  a  c2  0 
4 stock  a  c2  10 
5 stock  a  c2  10 
6 stock  b  c1  30 
7 stock  b  c1  30 
8 stock  b  c1  10 
9 stock  b  c2  0 
10 stock  b  c2  40 
11 stock  b  c2  40 

ein Schelm Säule (Lager) Es gibt, dass hier die Spaltenüberschrift in PIV konstant erscheint. Wenn wir es fallen zuerst die Schmelze arbeitet OOTB:

In [12]: piv.columns = piv.columns.droplevel(0) 

In [13]: pd.melt(piv) 
Out[13]: 
    goods category value 
0  a  c1  5 
1  a  c1  5 
2  a  c1  5 
3  a  c2  0 
4  a  c2  10 
5  a  c2  10 
6  b  c1  30 
7  b  c1  30 
8  b  c1  10 
9  b  c2  0 
10  b  c2  40 
11  b  c2  40 

Edit: Die oben tatsächlich den Index fällt, müssen Sie es eine Spalte mit reset_index machen:

In [21]: pd.melt(piv.reset_index(), id_vars=['month'], value_name='stock') 
Out[21]: 
    month goods category stock 
0  1  a  c1  5 
1  2  a  c1  5 
2  3  a  c1  5 
3  1  a  c2  0 
4  2  a  c2  10 
5  3  a  c2  10 
6  1  b  c1  30 
7  2  b  c1  30 
8  3  b  c1  10 
9  1  b  c2  0 
10  2  b  c2  40 
11  3  b  c2  40 
+0

Interessante Funktion, aber wo tat die Spalte 'Monat' gehen? – orange

+0

@orange der Index ap Birnen, die fallen gelassen werden, lassen diese Antwort hier, wie es einigen nützlich sein könnte (ich hoffe auch, dass ich es beheben kann!). –

+0

Sie denken, es ist ein Fehler oder ist das von Entwurf? – orange