1. ホーム
  2. python

pandasでMultiIndexインデックスカラムの値を問い合わせる方法

2023-09-12 22:10:58

質問

コードの例です。

In [171]: A = np.array([1.1, 1.1, 3.3, 3.3, 5.5, 6.6])

In [172]: B = np.array([111, 222, 222, 333, 333, 777])

In [173]: C = randint(10, 99, 6)

In [174]: df = pd.DataFrame(zip(A, B, C), columns=['A', 'B', 'C'])

In [175]: df.set_index(['A', 'B'], inplace=True)

In [176]: df
Out[176]: 
          C
A   B      
1.1 111  20
    222  31
3.3 222  24
    333  65
5.5 333  22
6.6 777  74 

では、Aの値を取得したいと思います。

Q1 : 範囲 [3.3, 6.6] - 期待される戻り値です。[3.3, 5.5, 6.6] または [3.3, 3.3, 5.5, 6.6] (最後に含まれる場合)、 [3.3, 5.5] または [3.3, 3.3, 5.5] (含まれない場合) です。

Q2 : 範囲 [2.0, 4.0] - 期待される戻り値です。[3.3]または[3.3、3.3]です。

他のどんな MultiIndex 次元、例えばB値など。

Q3 : 範囲 [111, 500] のデータ行数として、繰り返しのある範囲 - 期待される戻り値。[111, 222, 222, 333, 333]

より正式には

TがA,B,Cの列を持つ表であるとします。 n の行がある。表のセルは数字であり,例えばAはdouble,BとCはintegerである.を作ろう。 DataFrame を作成し、それをDFと名づける。DFのインデックスとしてA列とB列を設定する(重複しないように、つまりインデックスとしてA列とB列、データとして別々にはしない)、つまりこの場合A、Bとする。 マルチインデックス .

質問です。

  1. インデックスに対するクエリ、例えばラベル間隔 [120.0, 540.0] でインデックス A (または B) にクエリを発行するには、どのように書けばよいのでしょうか。ラベル120.0と540.0は存在します。私はクエリへの応答としてインデックスのリストにのみ興味があることを明確にしなければなりません!
  2. どのように同じように、しかし、ラベル120.0と540.0が存在しないが、120より低い値、120より高い値、540より小さい値、または540より高い値によるラベルが存在する場合?
  3. Q1とQ2の答えがユニークなインデックス値だった場合には、今、同じですが、インデックス範囲内のデータ行の数として、繰り返しで。

私は、インデックスではない列の場合、上記の質問に対する答えを知っていますが、インデックスの場合、Webでの長い調査と、機能性を実験した後 pandas の機能で実験した結果、成功しませんでした。私が今見ている唯一の方法(追加のプログラミングなしで)は、インデックスに加えて、データ列としてAとBの複製を持つことです。

どのように解決するには?

を問い合わせるには df によって MultiIndex の値によって、例えば (A > 1.7) と (B < 666) の場合 :

In [536]: result_df = df.loc[(df.index.get_level_values('A') > 1.7) & (df.index.get_level_values('B') < 666)]

In [537]: result_df
Out[537]: 
          C
A   B      
3.3 222  43
    333  59
5.5 333  56

したがって、例えば 'A' のインデックス値がまだ必要な場合は

In [538]: result_df.index.get_level_values('A')
Out[538]: Index([3.3, 3.3, 5.5], dtype=object)

問題は、大きなデータフレームでは インデックスによる での選択は、ソートされた通常の行の選択よりも10%ほどパフォーマンスが悪いということです。また、繰り返しの作業やループでは、遅延が蓄積されます。例を見てください。

In [558]: df = store.select(STORE_EXTENT_BURSTS_DF_KEY)

In [559]: len(df)
Out[559]: 12857

In [560]: df.sort(inplace=True)

In [561]: df_without_index = df.reset_index()

In [562]: %timeit df.loc[(df.index.get_level_values('END_TIME') > 358200) & (df.index.get_level_values('START_TIME') < 361680)]
1000 loops, best of 3: 562 µs per loop

In [563]: %timeit df_without_index[(df_without_index.END_TIME > 358200) & (df_without_index.START_TIME < 361680)]
1000 loops, best of 3: 507 µs per loop