2014-07-08 16 views
7

Mam dataframe, który wygląda tak:jak rozebranie stosu (lub obracać?) W pand

import pandas as pd 
datelisttemp = pd.date_range('1/1/2014', periods=3, freq='D') 
s = list(datelisttemp)*3 
s.sort() 
df = pd.DataFrame({'BORDER':['GERMANY','FRANCE','ITALY','GERMANY','FRANCE','ITALY','GERMANY','FRANCE','ITALY' ], 'HOUR1':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6],'HOUR2':[3 ,3 ,3, 5 ,5 ,5, 7, 7, 7], 'HOUR3':[8 ,8 ,8, 12 ,12 ,12, 99, 99, 99]}, index=s) 

To daje mi:

Out[458]: df 

      BORDER HOUR1 HOUR2 HOUR3 
2014-01-01 GERMANY  2  3  8 
2014-01-01 FRANCE  2  3  8 
2014-01-01 ITALY  2  3  8 
2014-01-02 GERMANY  4  5  12 
2014-01-02 FRANCE  4  5  12 
2014-01-02 ITALY  4  5  12 
2014-01-03 GERMANY  6  7  99 
2014-01-03 FRANCE  6  7  99 
2014-01-03 ITALY  6  7  99 

Chcę ostateczna dataframe wyglądać mniej więcej tak :

   HOUR GERMANY FRANCE ITALY 
2014-01-01 1  2  2  2  
2014-01-01 2  3  3  3 
2014-01-01 3  8  8  8 
2014-01-02 1  4  4  4 
2014-01-02 2  5  5  5 
2014-01-02 3 12  12  12 
2014-01-03 1  6  6  6 
2014-01-03 2  7  7  7 
2014-01-03 3 99  99  99 

zrobiłem następujące ale nie jestem całkiem tam:

df['date_col'] = df.index 

df2 = melt(df, id_vars=['date_col','BORDER']) 
#Can I keep the same index after melt or do I have to set an index like below? 
df2.set_index(['date_col', 'variable'], inplace=True, drop=True) 
df2 = df2.sort() 

df

Out[465]: df2 

         BORDER value 
date_col variable     
2014-01-01 HOUR1   GERMANY 2 
      HOUR1   FRANCE 2 
      HOUR1   ITALY  2 
      HOUR2   GERMANY 3 
      HOUR2   FRANCE 3 
      HOUR2   ITALY  3 
      HOUR3   GERMANY 8 
      HOUR3   FRANCE 8 
      HOUR3   ITALY  8 
2014-01-02 HOUR1   GERMANY 4 
      HOUR1   FRANCE 4 
      HOUR1   ITALY  4 
      HOUR2   GERMANY 5 
      HOUR2   FRANCE 5 
      HOUR2   ITALY  5 
      HOUR3   GERMANY 12 
      HOUR3   FRANCE 12 
      HOUR3   ITALY 12 
2014-01-03 HOUR1   GERMANY 6 
      HOUR1   FRANCE 6 
      HOUR1   ITALY  6 
      HOUR2   GERMANY 7 
      HOUR2   FRANCE 7 
      HOUR2   ITALY  7 
      HOUR3   GERMANY 99 
      HOUR3   FRANCE 99 
      HOUR3   ITALY 99 

Myślałem, że mogę rozebranie stosu df2 dostać coś, co przypomina moją ostateczną dataframe ale dostać wszelkiego rodzaju błędów. Próbowałem również obrócić tę ramkę danych, ale nie mogę uzyskać tego, czego chcę.

Odpowiedz

13

Chcemy, aby wartości (np. 'GERMANY') stały się nazwami kolumn, a nazwy kolumn (np. 'HOUR1') stały się wartościami - zamiany sortowania.

Metoda stack zamienia nazwy kolumn na wartości indeksu, a metoda przekształca wartości indeksu w nazwy kolumn.

Tak więc przesuwając wartości do indeksu, możemy użyć stack i unstack, aby wykonać zamianę.

import pandas as pd 

datelisttemp = pd.date_range('1/1/2014', periods=3, freq='D') 
s = list(datelisttemp)*3 
s.sort() 
df = pd.DataFrame({'BORDER':['GERMANY','FRANCE','ITALY','GERMANY','FRANCE','ITALY','GERMANY','FRANCE','ITALY' ], 'HOUR1':[2 ,2 ,2 ,4 ,4 ,4 ,6 ,6, 6],'HOUR2':[3 ,3 ,3, 5 ,5 ,5, 7, 7, 7], 'HOUR3':[8 ,8 ,8, 12 ,12 ,12, 99, 99, 99]}, index=s) 

df = df.set_index(['BORDER'], append=True) 
df.columns.name = 'HOUR' 
df = df.unstack('BORDER') 
df = df.stack('HOUR') 
df = df.reset_index('HOUR') 
df['HOUR'] = df['HOUR'].str.replace('HOUR', '').astype('int') 
print(df) 

daje

BORDER  HOUR FRANCE GERMANY ITALY 
2014-01-01  1  2  2  2 
2014-01-01  2  3  3  3 
2014-01-01  3  8  8  8 
2014-01-02  1  4  4  4 
2014-01-02  2  5  5  5 
2014-01-02  3  12  12  12 
2014-01-03  1  6  6  6 
2014-01-03  2  7  7  7 
2014-01-03  3  99  99  99 
+0

dziękuję za szczegółowe wyjaśnienia. Pomogło mi to lepiej zrozumieć stack/unstack. Dziękuję Ci. – codingknob

1

Używanie komputera df2:

>>> df2.pivot_table(values='value', index=['DATE', 'variable'], columns="BORDER") 
BORDER    FRANCE GERMANY ITALY 
DATE  variable       
2014-01-01 HOUR1   2  2  2 
      HOUR2   3  3  3 
      HOUR3   8  8  8 
2014-01-02 HOUR1   4  4  4 
      HOUR2   5  5  5 
      HOUR3   12  12  12 
2014-01-03 HOUR1   6  6  6 
      HOUR2   7  7  7 
      HOUR3   99  99  99 

[9 rows x 3 columns] 

Jest jeszcze trochę czyszczenia zrobić, jeśli chcesz przekonwertować „zmiennej” poziom indeksu na kolumnie o nazwie „godzina” i rozebrać się tekst „godzina” z wartości, ale myślę, że jest to podstawowy format, który chcesz.