web-dev-qa-db-fra.com

pandas multi-index - comment sélectionner le deuxième niveau en utilisant des colonnes?

Question stupide mais je ne trouve pas vraiment la réponse ..__ J'ai un dataframe avec cet index:

index = pd.MultiIndex.from_product([['stock1','stock2'...],['price','volume'...]])

C'est une structure utile pour pouvoir faire df['stock1'], mais comment sélectionner toutes les données de prix? Je ne peux pas donner un sens à la documentation.

J'ai essayé ce qui suit sans succès: df[:,'price']df[:]['price']df.loc(axis=1)[:,'close']df['price]

Si ce style d’indice est généralement considéré comme une mauvaise idée pour une raison quelconque, quel serait le meilleur choix? Devrais-je choisir un index multi-indexé pour les actions sous forme d’étiquettes sur la série chronologique plutôt que sur la colonne?

Merci beaucoup

EDIT - J'utilise le multi-index pour les colonnes, pas l'index (le libellé a eu raison de moi). Les exemples de la documentation se concentrent sur les index multiniveaux plutôt que sur les structures de colonnes.

13
AndyMoore

En utilisant également l'échantillon de données de John:

Utiliser xs() est un autre moyen de découper une MultiIndex:

df
               0
stock1 price   1
       volume  2
stock2 price   3
       volume  4
stock3 price   5
       volume  6

df.xs('price', level=1, drop_level=False)
              0
stock1 price  1
stock2 price  3
stock3 price  5

Sinon, si vous avez une MultiIndex à la place de colonnes:

df
  stock1        stock2        stock3       
   price volume  price volume  price volume
0      1      2      3      4      5      6

df.xs('price', axis=1, level=1, drop_level=False)
  stock1 stock2 stock3
   price  price  price
0      1      3      5
23
Andrew L

Utilisation de L’échantillon de données de @ JohnZwinck :

In [132]: df
Out[132]:
               0
stock1 price   1
       volume  2
stock2 price   3
       volume  4
stock3 price   5
       volume  6

Option 1:

In [133]: df.loc[(slice(None), slice('price')), :]
Out[133]:
              0
stock1 price  1
stock2 price  3
stock3 price  5

Option 2:

In [134]: df.loc[pd.IndexSlice[:, 'price'], :]
Out[134]:
              0
stock1 price  1
stock2 price  3
stock3 price  5
19
MaxU

df.unstack() "détachera" le dernier niveau de votre MultiIndex et rendra votre DataFrame beaucoup plus conventionnel, avec une colonne par type de données. Par exemple:

index = pd.MultiIndex.from_product([['stock1','stock2','stock3'],['price','volume']])
df = pd.DataFrame([1,2,3,4,5,6], index)
print(df.unstack())

Vous donne:

           0       
       price volume
stock1     1      2
stock2     3      4
stock3     5      6
4
John Zwinck

J'ai aussi remarqué que vous avez manqué cette option:

df.loc[:,"price"]

En tant que meilleure pratique pour vos données temporelles, conservez-les dans une colonne correspondant à des lignes, de préférence sous la forme d'un objet datetime en Python (les fonctionnalités de pandas le permettent. Vous pouvez utiliser la syntaxe de masque pour obtenir uniquement les heures correspondant à vos intérêts.

C'est ainsi que vous accédez à une seule colonne de votre cadre de données. Cependant, pour plusieurs colonnes, nous pouvons passer une liste ou deux points pour obtenir tous:

df.loc[:,["price","volume"]] 
#or
df.loc[:,:]

Une méthode utile pour interroger (et rapidement) consiste à utiliser des masques pour spécifier les lignes/colonnes répondant à la condition souhaitée:

Mask=df.loc[:,"price"]>50.0
df.loc[Mask, "stock"] #should return the stock prices greater than 50bucks. 

J'espère que cela vous aidera et, comme toujours, n'hésitez pas à donner suite à cette réponse si je comprenais complètement votre question, j'aimerais pouvoir vous aider davantage. 

0
bmc