web-dev-qa-db-ja.com

pandas複数の列のget_level_values

複数の列に対して _get_level_values_ の結果を取得する方法はありますか?

次のDataFrameが与えられます:

_         d
a b c     
1 4 10  16
    11  17
  5 12  18
2 5 13  19
  6 14  20
3 7 15  21
_

レベルaおよびcの値(、つまりタプルのリスト)を取得したい:

_[(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
_

注:

  • _get_level_values_に複数のレベルを与えることはできません(例:_df.index.get_level_values(['a','c']_)

  • 必要な各列に対して_get_level_values_を使用し、それらを一緒にZipすることができる回避策があります。

例えば:

_a_list = df.index.get_level_values('a').values
c_list = df.index.get_level_values('c').values

print([i for i in Zip(a_list,c_list)])
[(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
_

しかし、列の数が増えると面倒になります。

  • 例を作成するためのコードDataFrame

df = pd.DataFrame({'a':[1,1,1,2,2,3],'b':[4,4,5,5,6,7,],'c':[10,11,12,13,14,15], 'd':[16,17,18,19,20,21]}).set_index(['a','b','c'])

11
danielhadar

MultiIndex.tolist()メソッドは、MultiIndexのすべてのレベルのタプルのリストを提供します。たとえば、あなたの例ではDataFrame

_df.index.tolist()
# => [(1, 4, 10), (1, 4, 11), (1, 5, 12), (2, 5, 13), (2, 6, 14), (3, 7, 15)]
_

したがって、ここに2つのアイデアがあります。

  1. 元のMultiIndexからタプルのリストを取得し、結果をフィルタリングします。

    _[(a, c) for a, b, c in df.index.tolist()]
    # => [(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
    _

    この単純な方法の欠点は、必要なレベルの順序を手動で指定する必要があることです。代わりに、_itertools.compress_を利用して名前で選択できます。

    _from itertools import compress
    
    mask = [1 if name in ['a', 'c'] else 0 for name in df.index.names]
    [Tuple(compress(t, mask)) for t in df.index.tolist()]
    # => [(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
    _
  2. 必要なレベルを正確に持つMultiIndexを作成し、.tolist()を呼び出します。

    _df.index.droplevel('b').tolist()
    # => [(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
    _

    ドロップしたいレベルではなく、保持したいレベルに名前を付けたい場合は、次のようにすることができます。

    _df.index.droplevel([level for level in df.index.names
                    if not level in ['a', 'c']]).tolist()
    # => [(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
    _

選択したいインデックス名のリストを渡すことができる限り、これはそれほど面倒ではありません。

df.reset_index()[['a', 'c']].to_dict(orient='split')['data']

インデックスオブジェクトからレベル'a''b'を直接選択する方法が見つからなかったため、reset_indexを使用しました。

to_dictは、タプルではなくリストのリストを返すことに注意してください。

[[1, 10], [1, 11], [1, 12], [2, 13], [2, 14], [3, 15]]
1
IanS