pandasで特定の文字列を含む行を抽出(完全一致、部分一致)

pandasで特定の文字列を含む要素を持つ行を抽出する方法を説明します。 以下の方法があります。

完全一致

部分一致 str.contains(): 特定の文字列を含む str.endswith(): 特定の文字列で終わる str.startswith(): 特定の文字列で始まる str.match(): 正規表現のパターンに一致する

部分一致する行を抽出して抜き出すためには、pandasに準備されている文字列メソッド(str.xxx())を条件に応じて使います。

API Reference — pandas 0.23.0 documentation

ここではブールインデックスを用いたレガシーな方法を説明するが、query()メソッドを使うとより簡潔に書ける。以下の記事を参照。

今回は例として以下のデータを使用します。

import pandas as pd

df = pd.read_csv('data/src/sample_pandas_normal.csv').head(3)
print(df)
#       name  age state  point
# 0    Alice   24    NY     64
# 1      Bob   42    CA     92
# 2  Charlie   18    CA     70

サンプルのcsvファイルはコチラ。

sample_pandas_normal.csv

例はpandas.DataFrameだが、pandas.Seriesでも同様。 データ(要素)ではなく、行名や列名に対して文字列メソッドを適用し、条件を満たす行や列を抽出することもできます。以下の記事を参照。

行を抽出(選択)する方法

まず、pandas.DataFrameから行を抽出(選択)して新しいpandas.DataFrameを取得する方法を示す。 真偽値boolのリスト(配列)またはpandas.Seriesを使うと、Trueの行だけが抽出(選択)できます。

mask = [True, False, True]
df_mask = df[mask]
print(df_mask)
#       name  age state  point
# 0    Alice   24    NY     64
# 2  Charlie   18    CA     70

したがって、文字列要素を持つ列に対して条件に応じたboolのリストを取得できればよい。 完全一致(==) ==を使うと、要素が文字列に完全一致するとTrueとなるpandas.Seriesを取得できます。

print(df['state'] == 'CA')
# 0    False
# 1     True
# 2     True
# Name: state, dtype: bool

df_exact = df[df['state'] == 'CA']
print(df_exact)
#       name  age state  point
# 1      Bob   42    CA     92
# 2  Charlie   18    CA     70

str.contains(): 特定の文字列を含む

pandas.Seriesの文字列メソッドstr.contains()を使うと、要素が特定の文字列を含むとTrueとなるpandas.Seriesを取得できます。

pandas.Series.str.contains — pandas 0.21.1 documentation

print(df['name'].str.contains('l'))
# 0     True
# 1    False
# 2     True
# Name: name, dtype: bool

df_contains = df[df['name'].str.contains('l')]
print(df_contains)
#       name  age state  point
# 0    Alice   24    NY     64
# 2  Charlie   18    CA     70

要素が欠損値NaNである場合、デフォルトではTrueでもFalseでもなくNaNを返す。このため、そのpandas.Seriesを使って行を抽出するとエラーになる。 str.contains()の引数naでNaNの結果を置き換える値を指定できます。na=TrueとすればNaNの行も選択され、na=FalseとすればNaNの行は選択されない。

str.endswith(): 特定の文字列で終わる

pandas.Seriesの文字列メソッドstr.endswith()を使うと、要素が特定の文字列で終わるとTrueとなるpandas.Seriesを取得できます。

pandas.Series.str.endswith — pandas 0.21.1 documentation

print(df['name'].str.endswith('e'))
# 0     True
# 1    False
# 2     True
# Name: name, dtype: bool

df_endswith = df[df['name'].str.endswith('e')]
print(df_endswith)
#       name  age state  point
# 0    Alice   24    NY     64
# 2  Charlie   18    CA     70

str.endswith()も引数naを持つ。欠損値NaNの行を選択したい場合はna=True、選択したくない場合はna=Falseとします。

str.startswith(): 特定の文字列で始まる

pandas.Seriesの文字列メソッドstr.startswith()を使うと、要素が特定の文字列で始まるとTrueとなるpandas.Seriesを取得できます。

pandas.Series.str.startswith — pandas 0.21.1 documentation

print(df['name'].str.startswith('B'))
# 0    False
# 1     True
# 2    False
# Name: name, dtype: bool

df_startswith = df[df['name'].str.startswith('B')]
print(df_startswith)
#   name  age state  point
# 1  Bob   42    CA     92

str.startswith()も引数naを持つ。欠損値NaNの行を選択したい場合はna=True、選択したくない場合はna=Falseとします。

str.match(): 正規表現のパターンに一致する

pandas.Seriesの文字列メソッドstr.match()を使うと、要素が正規表現のパターンに一致するとTrueとなるpandas.Seriesを取得できます。

pandas.Series.str.match — pandas 0.21.1 documentation

print(df['name'].str.match('.*i.*e'))
# 0     True
# 1    False
# 2     True
# Name: name, dtype: bool

df_match = df[df['name'].str.match('.*i.*e')]
print(df_match)
#       name  age state  point
# 0    Alice   24    NY     64
# 2  Charlie   18    CA     70

str.match()も引数naを持つ。欠損値NaNの行を選択したい場合はna=True、選択したくない場合はna=Falseとします。

シェア

関連カテゴリー

Python pandas 正規表現

pandasの文字列を区切り文字や正規表現で複数の列に分割 pandas-datareaderで株価や人口のデータを取得 pandasのdescribeで各列の要約統計量(平均、標準偏差など)を取得 pandasで分位数・パーセンタイルを取得するquantile 『Python Data Science Handbook』(英語の無料オンライン版あり) pandasのバージョンを確認(pd.show_versions) pandasの表示設定変更(小数点以下桁数、有効数字、最大行数・列数など) PythonでRESAS APIを使ってデータをダウンロード Pythonで文字列を置換(replace, translate, re.sub, re.subn) Pythonの正規表現モジュールreの関数match、search、sub pandasで行数、列数、全要素数(サイズ)を取得 pandas.DataFrameから条件を満たす行名・列名の行・列を抽出(選択) pandasの時系列データのタイムゾーンを処理(tz_convert, tz_localize) pandas参考書『Pythonによるデータ分析入門』の注意点 pandas.DataFrameに列や行を追加(assign, appendなど)

Last Updated: 6/26/2019, 10:34:03 PM