pandas.DataFrameの行・列を行名・列名の条件で抽出するfilter
pandasのDataFrame, Seriesから、特定の条件を満たす行名・列名の行・列を抽出するにはfilter()メソッドを使う。
- pandas.DataFrame.filter — pandas 2.1.4 documentation
- pandas.Series.filter — pandas 2.1.4 documentation
行名・列名ではなく要素が条件を満たす行を抽出する方法については以下の記事を参照。
- 関連記事: pandas.DataFrameの行を条件で抽出するquery
- 関連記事: pandasで複数条件のAND, OR, NOTから行を抽出(選択)
- 関連記事: pandasで特定の文字列を含む行を抽出(完全一致、部分一致)
特定のデータ型dtypeの列を抽出・除外することも可能。
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。以下のDataFrameを例とする。
import pandas as pd
print(pd.__version__)
# 2.1.4
df = pd.DataFrame([[0, 1, 2], [3, 4, 5], [6, 7, 8]],
index=['apple', 'banana', 'pineapple'],
columns=['A', 'B', 'C'])
print(df)
# A B C
# apple 0 1 2
# banana 3 4 5
# pineapple 6 7 8
pandas.DataFrame.filter()の基本的な使い方
DataFrameのfilter()メソッドで、条件を満たす行名・列名の行・列を抽出できる。
引数items, like, regexのいずれかで条件を指定する。同時に指定するとエラー。それぞれの詳細に付いては後述。
print(df.filter(items=['A', 'C']))
# A C
# apple 0 2
# banana 3 5
# pineapple 6 8
# print(df.filter(items=['A', 'C'], like='A'))
# TypeError: Keyword arguments `items`, `like`, or `regex` are mutually exclusive
条件を満たす行名・列名が存在しない場合は空のDataFrameが返される。エラーにはならない。
print(df.filter(items=['X']))
# Empty DataFrame
# Columns: []
# Index: [apple, banana, pineapple]
行・列を指定: 引数axis
行・列どちらを対象とするかは引数axisで指定する。0または'index'で行、1またはcolumnsで列が対象となる。
print(df.filter(items=['apple', 'pineapple'], axis=0))
# A B C
# apple 0 1 2
# pineapple 6 7 8
print(df.filter(items=['apple', 'pineapple'], axis='index'))
# A B C
# apple 0 1 2
# pineapple 6 7 8
print(df.filter(items=['A', 'C'], axis=1))
# A C
# apple 0 2
# banana 3 5
# pineapple 6 8
print(df.filter(items=['A', 'C'], axis='columns'))
# A C
# apple 0 2
# banana 3 5
# pineapple 6 8
省略した場合は列が対象となる。
print(df.filter(items=['A', 'C']))
# A C
# apple 0 2
# banana 3 5
# pineapple 6 8
行・列に対して同時に条件を指定することはできない。行・列両方を対象としたい場合はfilter()を繰り返す。
print(df.filter(items=['A', 'C']).filter(items=['apple', 'pineapple'], axis=0))
# A C
# apple 0 2
# pineapple 6 8
行名・列名が完全一致する行・列を抽出: 引数items
行名・列名が完全一致する行・列を抽出するには、引数itemsにリストを指定する。結果の行・列の順番は指定したリストの順番となる。元の順番ではないので注意。
print(df.filter(items=['A', 'C']))
# A C
# apple 0 2
# banana 3 5
# pineapple 6 8
print(df.filter(items=['C', 'A']))
# C A
# apple 2 0
# banana 5 3
# pineapple 8 6
同様の処理は[]やloc[]でリストを指定することでも実現可能。結果が指定したリストの順番となるのも同じ。
print(df[['C', 'A']])
# C A
# apple 2 0
# banana 5 3
# pineapple 8 6
print(df.loc[:, ['C', 'A']])
# C A
# apple 2 0
# banana 5 3
# pineapple 8 6
print(df.loc[['pineapple', 'apple']])
# A B C
# pineapple 6 7 8
# apple 0 1 2
行名・列名が部分一致する行・列を抽出: 引数like
行名・列名が部分一致する(〜を含む)行・列を抽出するには、引数likeに文字列を指定する。
print(df.filter(like='apple', axis=0))
# A B C
# apple 0 1 2
# pineapple 6 7 8
行名・列名labelと引数likeに対してlike in label == Trueとなる行・列が抽出される。in演算子についての詳細は以下の記事を参照。
複数条件を指定したい場合は次に述べる正規表現を使う。
行名・列名を正規表現で選択して行・列を抽出: 引数regex
行名・列名を正規表現で選択して行・列を抽出するには、引数regexに正規表現パターンを文字列で指定する。
正規表現の特殊文字などについては以下を参照。
行名が'e'で終わる行を抽出。
print(df.filter(regex='e$', axis=0))
# A B C
# apple 0 1 2
# pineapple 6 7 8
行名が'a'または'b'で始まる行を抽出。
print(df.filter(regex='^(a|b)', axis=0))
# A B C
# apple 0 1 2
# banana 3 4 5
行名が'na'または'ne'を含む行を抽出。
print(df.filter(regex='(na|ne)', axis=0))
# A B C
# banana 3 4 5
# pineapple 6 7 8
行名・列名labelと引数regexに対してre.search(regex, label) == Trueとなる行・列が抽出される。re.search()についての詳細は以下の記事を参照。
pandas.Series.filter()
Seriesでもfilter()メソッドが提供されている。使い方はDataFrameと同じ。
s = pd.Series([0, 1, 2], index=['apple', 'banana', 'pineapple'])
print(s)
# apple 0
# banana 1
# pineapple 2
# dtype: int64
print(s.filter(items=['pineapple', 'banana']))
# pineapple 2
# banana 1
# dtype: int64
print(s.filter(like='apple'))
# apple 0
# pineapple 2
# dtype: int64
print(s.filter(regex='^(a|b)'))
# apple 0
# banana 1
# dtype: int64