はじめに
pythonのpandasデータフレームを使っている場合に、該当の要素の値を取得するケースを想定しています。 要素を取得する為には、df.iloc[行番号, 列番号] などと指定すれば要素は取得できるようですが、今回は、行名、列名を部分一致で検索して部分一致した行番号、列番号を取得して、そして要素を取得する方法を記載しておきます。
やりたいこと
-
Pandasデータフレームから要素(セルの値)を取得する。
-
行番号、列番号を指定して要素(セルの値)を取得する。
-
指定する行番号の行名及び、列番号の列名は部分一致で検索する。
部分一致で検索した列の列番号を取得する。
ヘッダーの列名を部分一致で検索したいときは、下記のように「df.columns.str.contains("部分一致ワード")」で検索できます。 検索した結果をリスト化(.tolist())すると、部分一致した列がTrueとなってリスト化されます。
import pandas as pd
df = pd.read_csv("csvファイルのパス") # csvファイルをデータフレームとして読み込み
bubun_icchi_retu = df.columns.str.contains("部分一致ワード") # ヘッダー(列のタイトル)を部分一致で検索
bubun_icchi_retu = bubun_icchi_retu.tolist() # ヘッダーを部分一致で検索した結果をリスト化
print(bubun_icchi_retu) # --> [False, False, True]
True、Falseのリストになりましたので、このTrue/Falseリストから部分一致したTrueがリストの何番目かを取得します。 この部分一致したTrueが何番目かという情報を、元々のデータフレームの列番号としてそのまま使用します。
retu_bango = bubun_icchi_retu.index(True) # 部分一致したTrueがリストの何番目かを取得
gyo_bango = 2 # 今回は実行例として行番号が2の行を取得します。
taisyo_no_atai = df.iloc[gyo_bango, retu_bango] # データフレームから行番号、列番号をしてして値を取得
部分一致で検索した行の行番号を取得する。
列番号を取得した流れで、行番号も取得できます。 ヘッダーの列名を部分一致で検索したいときは、下記のように「df.index.str.contains("部分一致ワード")」で検索できます。 部分一致ワードの検索の対象となる列は、インデックス登録してある列が対象となります。 検索した結果をリスト化(tolist())すると、部分一致した列がTrueとなってリスト化されます。
import pandas as pd
df = pd.read_csv("csvファイルのパス", index_col=0) # csvファイルをデータフレームとして読み込み。CSVファイル内の先頭列(0)をインデックス(目次みたいなもの)として指定。
bubun_icchi_gyou = df.index.str.contains("部分一致ワード") # インデックスとして指定した列から部分一致ワードで部分一致する行を検索
bubun_icchi_gyou = bubun_icchi_retu.tolist() # インデックスを部分一致で検索した結果をリスト化
print(bubun_icchi_retu) # --> [False, False, True, False, False]
あとは、上記の列番号を取得したのと同じ流れで、最終的にデータフレームの要素を取得できます。
retu_bango = 2 # 今回は実行例として列番号が2の列を取得します。
gyo_bango = bubun_icchi_gyou.index(True) # 部分一致したTrueがリストの何番目かを取得
taisyo_no_atai = df.iloc[gyo_bango, retu_bango] # データフレームから行番号、列番号をしてして値を取得
補足
-
上記の列番号を取得する方法と、行番号を取得する方法を組み合わせることで、列名、行名を両方とも部分一致検索で検索できるようになります。
-
列名、あるいは行名を部分一致で検索した場合に、複数の列あるいは複数の行がヒットすることもあるかもしれません。複数の行あるいは複数の列がヒットした場合は、以下のようにリスト化した際に、複数のTrueがリストに入っていますので、Trueの数で条件分岐できます。
import pandas as pd df = pd.read_csv(csvファイルのパス) bubun_icchi_retu = df.columns.str.contains(部分一致ワード) bubun_icchi_retu = bubun_icchi_retu.tolist() print(bubun_icchi_retu) # --> [False, True, True] if bubun_icchi_retu.count(True) == 1: # 部分一致の結果が1件だった場合の処理。 pass elif bubun_icchi_retu.count(True) >= 2: # 部分一致の結果が2件以上だった場合の処理。 pass
-
部分一致検索で複数の行あるいは複数の列がヒットした場合は、以下のようにリスト化した際に、複数のTrueがリストに入ってきますが、リストにTrueが何番目に入っているかを調べるindex()は、Trueが複数あるい場合は先頭のTrueの位置を返します。
true_list = [False, True, True] true_no_ichi = true_list.index(True) # 部分一致したTrueがリストの何番目かを取得 print(true_no_ichi) # --> 1
リスト(true_list)のインデックスが2の箇所にもTrueがありますが、index()で検索されるTrueは、最初に一致した箇所(インデックスが1の箇所)のみになります。