web-dev-qa-db-fra.com

Sélectionnez un seul index de DataFrame multi-index

J'essaie de créer un nouveau DataFrame en utilisant un seul index à partir d'un DataFrame multi-indexé.

                   A         B         C
first second                              
bar   one     0.895717  0.410835 -1.413681
      two     0.805244  0.813850  1.607920
baz   one    -1.206412  0.132003  1.024180
      two     2.565646 -0.827317  0.569605
foo   one     1.431256 -0.076467  0.875906
      two     1.340309 -1.187678 -2.211372
qux   one    -1.170299  1.130127  0.974466
      two    -0.226169 -1.436737 -2.006747

Idéalement, je voudrais quelque chose comme ça:

In: df.ix[level="first"]

et:

Out:

               A         B         C
first                               
bar        0.895717  0.410835 -1.413681
           0.805244  0.813850  1.607920
baz       -1.206412  0.132003  1.024180
           2.565646 -0.827317  0.569605
foo        1.431256 -0.076467  0.875906
           1.340309 -1.187678 -2.211372
qux       -1.170299  1.130127  0.974466
          -0.226169 -1.436737 -2.006747
`

Essentiellement, je veux supprimer tous les autres index du multi-index autres que le niveau first. Y a-t-il un moyen facile de faire ceci?

27
Skorpeo

Une façon pourrait être de simplement relier df.index au niveau souhaité du MultiIndex. Vous pouvez le faire en spécifiant le nom d'étiquette que vous souhaitez conserver:

df.index = df.index.get_level_values('first')

ou utilisez la valeur entière du niveau:

df.index = df.index.get_level_values(0)

Tous les autres niveaux du MultiIndex disparaîtraient ici.

31
Alex Riley

La solution est relativement nouvelle et utilise le df.xs fonctionne comme

In [88]: df.xs('bar', level='first')
Out[88]:
Second  Third
one     A       -2.315312
        B        0.497769
        C        0.108523
two     A       -0.778303
        B       -1.555389
        C       -2.625022
dtype: float64

Peut également faire avec plusieurs indices comme

In [89]: df.xs(('bar', 'A'), level=('First', 'Third'))
Out[89]:
Second
one   -2.315312
two   -0.778303
dtype: float64

La configuration des exemples est ci-dessous

import pandas as pd
import numpy as np
arrays = [
    np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
    np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])
]
index = pd.MultiIndex.from_tuples(list(Zip(*arrays)), names=['first', 'second'])
df = pd.DataFrame(np.random.randn(3, 8), index=['A', 'B', 'C'], columns=index)
df.index.names = pd.core.indexes.frozen.FrozenList(['First', 'Second', 'Third'])
df = df.unstack()
16