2016-06-09 4 views
3

Ich habe einen DataFrame mit zwei Spalten im Index - einer ist eine Bezeichnung, der andere ist eine Zeitreihe. Ich möchte die vorherige Zeile für jede Zeile in der Zeitreihe abrufen. Aber ich kann DataFrame.shift() nicht verwenden, weil es zwei Spalten im Index gibt und die Verschiebung die Beschriftungen durcheinanderbringt.Pandas bekommen vorherige Reihe von Zeitreihen mit multiplen Index

#Desired behavior: each 'x' row needs its prev value, each 'y' row needs 
#its prev value, etc. DON'T put the 'y' row's prev value on the 'x' row. 
#Have to respect both columns on the index when shifting. 
x = pandas.DataFrame({ 'label' : [ 'x', 'y', 'z', 'x', 'y', 'z', 'x', 'y', 'z' ], 
    'period' : [ 1, 1, 1, 2, 2, 2, 3, 3, 3 ], 
    'value' : [ '1st x', '1st y', '1st z', '2nd x', '2nd y', '2nd z', '3rd x', '3rd y', '3rd z' ]}) 
x.set_index(['label', 'period'], inplace=True) 

#That looks like: 
>>> x 
      value 
label period  
x  1  1st x 
y  1  1st y 
z  1  1st z 
x  2  2nd x 
y  2  2nd y 
z  2  2nd z 
x  3  3rd x 
y  3  3rd y 
z  3  3rd z 

#I can't use x.shift(1) because that mixes the 'x' and 'y' values: 
>>> x.shift(1) 
       value 
label period  
x  1   NaN 
y  1  1st x ###WRONG! should be NaN 
z  1  1st y ###WRONG! Should be Nan 
x  2  1st z ###WRONG!!! This should be "1st x' 
y  2  2nd x ###Wrong!! Should be '1st y' 
z  2  2nd y ###Wrong!! Should be '1st z' 
x  3  2nd z ###Wrong!! Should be '2nd x' 
y  3  3rd x #WRONG! should be '2nd y' 
z  3  3rd y #WRONG! should be '2nd z' 

Wie kann ich die richtige vorherige Zeile für jede Zeile erhalten?

Antwort

3

Wenn Sie groupby durch die erste Indexebene dann shift funktionieren wie gewünscht:

In [42]: 
x.groupby(level='label').shift() 

Out[42]: 
       value 
label period  
x  1   NaN 
y  1   NaN 
z  1   NaN 
x  2  1st x 
y  2  1st y 
z  2  1st z 
x  3  2nd x 
y  3  2nd y 
z  3  2nd z 
0

Auch, wenn Sie es in einem 'lesbar' Format wollen, können Sie die DataFrame.unstack

unstacked = df.unstack(level=0) 
changes = unstacked.diff() 
verwenden könnten

, die für Daten wie:

label period value  
x  1  1 
y  1  0 
z  1  3 
x  2  2 
y  2  1 
z  2  2 
x  3  1 
y  3  0 
z  3  0 

Produziert:

value 
label x y z 
period   
1 NaN  NaN  NaN 
2 1.0  1.0  -1.0 
3 -1.0 -1.0 -2.0