2015-10-07 15 views
5

Quando si impila un panda DataFrame, viene restituito un Series. Normalmente dopo aver impilato uno DataFrame, lo converto nuovamente in DataFrame. Tuttavia, i nomi predefiniti provenienti dai dati in pila rendono il cambio di nome delle colonne un po 'hacky. Quello che sto cercando è un modo più semplice/integrato per dare alle colonne nomi sensibili dopo l'impilamento.Impostare i nomi delle colonne quando si impilano i panda DataFrame

Ad esempio, per i seguenti DataFrame:

In [64]: df = pd.DataFrame({'id':[1,2,3], 
    ...:     'date':['2015-09-31']*3, 
    ...:     'value':[100, 95, 42], 
    ...:     'value2':[200, 57, 27]}).set_index(['id','date']) 

In [65]: df 
Out[65]: 
       value value2 
id date      
1 2015-09-31 100  200 
2 2015-09-31  95  57 
3 2015-09-31  42  27 

ho stack e riconvertirlo in un DataFrame in questo modo:

In [68]: df.stack().reset_index() 
Out[68]: 
    id  date level_2 0 
0 1 2015-09-31 value 100 
1 1 2015-09-31 value2 200 
2 2 2015-09-31 value 95 
3 2 2015-09-31 value2 57 
4 3 2015-09-31 value 42 
5 3 2015-09-31 value2 27 

Quindi, al fine di nominare queste colonne in modo appropriato avrei bisogno di fare qualcosa del genere:

In [72]: stacked = df.stack() 

In [73]: stacked 
Out[73]: 
id date    
1 2015-09-31 value  100 
       value2 200 
2 2015-09-31 value  95 
       value2  57 
3 2015-09-31 value  42 
       value2  27 
dtype: int64 

In [74]: stacked.index.set_names('var_name', level=len(stacked.index.names)-1, inplace=True) 

In [88]: stacked.reset_index().rename(columns={0:'value'}) 
Out[88]: 
    id  date var_name value 
0 1 2015-09-31 value 100 
1 1 2015-09-31 value2 200 
2 2 2015-09-31 value  95 
3 2 2015-09-31 value2  57 
4 3 2015-09-31 value  42 
5 3 2015-09-31 value2  27 

Idealmente, la soluzione sarebbe simile a questa:

df.stack(new_index_name='var_name', new_col_name='value') 

Ma guardando il docs che non sembra stack prende tali argomenti. C'è un modo più semplice/integrato nei panda per gestire questo flusso di lavoro?

risposta

5

pd.melt è spesso utile per la conversione DataFrames da "ampia" in formato "lungo". Si potrebbe usare pd.melt qui se si converte i livelli di indice e iddate alle colonne prima:

In [56]: pd.melt(df.reset_index(), id_vars=['id', 'date'], value_vars=['value', 'value2'], var_name='var_name', value_name='value') 
Out[56]: 
    id  date var_name value 
0 1 2015-09-31 value 100 
1 2 2015-09-31 value  95 
2 3 2015-09-31 value  42 
3 1 2015-09-31 value2 200 
4 2 2015-09-31 value2  57 
5 3 2015-09-31 value2  27 
+1

+1, ma un po 'di elaborazione sarebbe l'ideale. Forse anche capitale inizia i nomi delle colonne come mi sono confuso con così tanti 'value's su. – josh

7

Quindi, ecco un modo che potresti trovare un po 'più pulito, utilizzando il fatto che columns e Series possono anche contenere nomi.

In [45]: df 
Out[45]: 
       value value2 
id date      
1 2015-09-31 100  200 
2 2015-09-31  95  57 
3 2015-09-31  42  27 

In [46]: df.columns.name = 'var_name' 

In [47]: s = df.stack() 

In [48]: s.name = 'value' 

In [49]: s.reset_index() 
Out[49]: 
    id  date var_name value 
0 1 2015-09-31 value 100 
1 1 2015-09-31 value2 200 
2 2 2015-09-31 value  95 
3 2 2015-09-31 value2  57 
4 3 2015-09-31 value  42 
5 3 2015-09-31 value2  27 
Problemi correlati