Python Pandasで基準に基づいてデータフレームの最初の行を取得する 質問する

Python Pandasで基準に基づいてデータフレームの最初の行を取得する 質問する

次のようなDataFrameがあるとします

import pandas as pd

df = pd.DataFrame([
            [1, 2, 1], [1, 3, 2], [4, 6, 3], [4, 3, 4], [5, 4, 5]
        ], columns=['A', 'B', 'C'])

>> df
   A  B  C
0  1  2  1
1  1  3  2
2  4  6  3
3  4  3  4
4  5  4  5

元の DataFrame は、列と行が多くなり、より複雑になっています。

いくつかの条件を満たす最初の行を取得したいです。例:

  1. A > 3 となる最初の行を取得します (行 2 を返します)
  2. A > 4 AND B > 3 となる最初の行を取得します (行 4 を返します)
  3. A > 3 AND (B > 3 OR C > 2) となる最初の行を取得します (行 2 を返します)

しかし、特定の基準を満たす行がない場合は、A (または他の場合は B、C など) で降順に並べ替えた後、最初の行を取得したいと思います。

  1. A > 6 の最初の行を取得します (A の降順で並べ替えて行 4 を返し、最初の行を取得します)

DataFrame を反復処理することで、これを実現できました (これはひどいことだとわかっています :P)。では、これを解決するためのより Python 的な方法は何でしょうか?

ベストアンサー1

このチュートリアルpandas のスライスに非常に適しています。ぜひチェックしてみてください。いくつかのスニペットを紹介します... 条件付きでデータフレームをスライスするには、次の形式を使用します。

>>> df[condition]

これにより、 を使用してインデックスを作成できるデータフレームのスライスが返されますiloc。例を次に示します。

  1. A > 3 となる最初の行を取得します (行 2 を返します)

    >>> df[df.A > 3].iloc[0]
    A    4
    B    6
    C    3
    Name: 2, dtype: int64
    

実際に必要なのが行番号である場合は、 を使用するのではなくiloc、 を使用しますdf[df.A > 3].index[0]

  1. A > 4 AND B > 3 となる最初の行を取得します。

    >>> df[(df.A > 4) & (df.B > 3)].iloc[0]
    A    5
    B    4
    C    5
    Name: 4, dtype: int64
    
  2. A > 3 AND (B > 3 OR C > 2) となる最初の行を取得します (行 2 を返します)

    >>> df[(df.A > 3) & ((df.B > 3) | (df.C > 2))].iloc[0]
    A    4
    B    6
    C    3
    Name: 2, dtype: int64
    

さて、最後のケースでは、降順でソートされたフレームを返すデフォルトのケースを処理する関数を記述できます。

>>> def series_or_default(X, condition, default_col, ascending=False):
...     sliced = X[condition]
...     if sliced.shape[0] == 0:
...         return X.sort_values(default_col, ascending=ascending).iloc[0]
...     return sliced.iloc[0]
>>> 
>>> series_or_default(df, df.A > 6, 'A')
A    5
B    4
C    5
Name: 4, dtype: int64

予想どおり、行 4 が返されます。

おすすめ記事