2012-11-05 14 views
30

Così ho imparato che posso usare DataFrame.groupby senza avere un MultiIndex per fare sottocampionamento/sezioni trasversali.Benefici del multiindice del panda?

D'altra parte, quando ho un MultiIndex su un DataFrame, ho ancora bisogno di usare DataFrame.groupby per fare sub-campionamento/sezioni trasversali.

Quindi, a cosa serve un MultiIndex a parte la visualizzazione abbastanza utile e carina delle gerarchie durante la stampa?

risposta

58

L'indicizzazione gerarchica (denominata anche indicizzazione "multi-livello") è stata introdotta nella versione 0.4 di pandas.

Questo apre le porte ad analisi e manipolazioni di dati piuttosto sofisticate, in particolare per il lavoro con dati dimensionali superiori. In sostanza, consente, ad esempio, di archiviare e manipolare in modo efficace dati ad alta dimensione arbitrariamente in una struttura tabulare bidimensionale (DataFrame).

Immaginate la costruzione di un dataframe utilizzando MultiIndex in questo modo: -

import pandas as pd 
import numpy as np 

np.arrays = [['one','one','one','two','two','two'],[1,2,3,1,2,3]] 

df = pd.DataFrame(np.random.randn(6,2),index=pd.MultiIndex.from_tuples(list(zip(*np.arrays))),columns=['A','B']) 

df # This is the dataframe we have generated 

      A   B 
one 1 -0.732470 -0.313871 
    2 -0.031109 -2.068794 
    3 1.520652 0.471764 
two 1 -0.101713 -1.204458 
    2 0.958008 -0.455419 
    3 -0.191702 -0.915983 

Questo df è semplicemente una struttura di dati di due dimensioni

df.ndim 

2 

ma possiamo immaginare, guardando l'uscita, come una struttura dati tridimensionale.

  • one con 1 con i dati -0.732470 -0.313871.
  • one con 2 con dati -0.031109 -2.068794.
  • one con 3 con dati 1.520652 0.471764.

A.k.a .: "effettivamente memorizzare e manipolare i dati arbitrariamente elevate dimensioni in una struttura tabellare 2-dimensionale"

Questa non è solo una "bella mostra". Ha il vantaggio di un facile recupero dei dati poiché ora abbiamo un indice gerarchico.

Ad esempio.

In [44]: df.ix["one"] 
Out[44]: 
      A   B 
1 -0.732470 -0.313871 
2 -0.031109 -2.068794 
3 1.520652 0.471764 

ci fornirà un nuovo frame di dati solo per il gruppo di dati appartenenti a "uno".

E possiamo restringere la nostra selezione dei dati ulteriormente in questo modo: -

In [45]: df.ix["one"].ix[1] 
Out[45]: 
A -0.732470 
B -0.313871 
Name: 1 

E, naturalmente, se vogliamo un valore specifico, ecco un esempio: -

In [46]: df.ix["one"].ix[1]["A"] 
Out[46]: -0.73247029752040727 

Quindi, se abbiamo ancora più indici (oltre ai 2 indici mostrati nell'esempio sopra), possiamo essenzialmente approfondire e selezionare il set di dati a cui siamo veramente interessati senza la necessità di groupby.

Possiamo anche prendere una sezione trasversale (righe o colonne) dal nostro dataframe ...

By righe: -

In [47]: df.xs('one') 
Out[47]: 
      A   B 
1 -0.732470 -0.313871 
2 -0.031109 -2.068794 
3 1.520652 0.471764 

da colonne: -

In [48]: df.xs('B', axis=1) 
Out[48]: 
one 1 -0.313871 
    2 -2.068794 
    3 0.471764 
two 1 -1.204458 
    2 -0.455419 
    3 -0.915983 
Name: B 
+6

Le 3 coppie di dati nel primo descrizione della struttura dei dati dimensionale 3 ('una con 1 con i dati -0.790620 0.229276 . '...) non sembrano corrispondere a nessun dato nel tuo esempio attuale. – Gerrat

+0

C'è qualche ragione particolare per utilizzare MultiIndex.from_tuples (elenco (zip (* np.arrays)) quando è disponibile il metodo from_arrays? df = pd.DataFrame (np.random.randn (6,2), indice = pd.MultiIndex.from_arrays (np.arrays), colonne = [ 'A', 'B']) –

Problemi correlati