いずれかの列で正規表現を使用してデータフレームをきれいにフィルター処理したいと思います。
不自然な例:
In [210]: foo = pd.DataFrame({'a' : [1,2,3,4], 'b' : ['hi', 'foo', 'fat', 'cat']})
In [211]: foo
Out[211]:
a b
0 1 hi
1 2 foo
2 3 fat
3 4 cat
正規表現を使用して、f
で始まる行にフィルターをかけたいです。最初に行く:
In [213]: foo.b.str.match('f.*')
Out[213]:
0 []
1 ()
2 ()
3 []
それはあまり便利ではありません。しかし、これは私のブールインデックスを取得します:
In [226]: foo.b.str.match('(f.*)').str.len() > 0
Out[226]:
0 False
1 True
2 True
3 False
Name: b
そのため、次の方法で制限を行うことができます。
In [229]: foo[foo.b.str.match('(f.*)').str.len() > 0]
Out[229]:
a b
1 2 foo
2 3 fat
しかし、そうすることで、人工的に正規表現にグループを入れることができ、クリーンな方法ではないようです。これを行うためのより良い方法はありますか?
代わりに contains を使用してください:
In [10]: df.b.str.contains('^f')
Out[10]:
0 False
1 True
2 True
3 False
Name: b, dtype: bool
データフレームを使用した複数列の検索:
frame[frame.filename.str.match('*.'+MetaData+'.*') & frame.file_path.str.match('C:\test\test.txt')]
これは少し遅れる可能性がありますが、これはパンダで行う方が簡単になりました。 as_indexer=True
でmatchを呼び出して、ブール値の結果を取得できます。これは(match
とcontains
の違いと共に)文書化されています here 。
文字列処理関数Series.str.startwith()
が既にあります。
foo[foo.b.str.startswith('f')]
を試してください。
結果:
a b
1 2 foo
2 3 fat
あなたが期待することだと思います。
@ user3136169のすばらしい回答に感謝します。NoneType値を削除する方法の例を次に示します。
def regex_filter(val):
if val:
mo = re.search(regex,val)
if mo:
return True
else:
return False
else:
return False
df_filtered = df[df['col'].apply(regex_filter)]
正規表現をチェックし、列に適用を使用するブール関数を作成します
foo[foo['b'].apply(regex_function)]
str
スライスを使用する
foo[foo.b.str[0]=='f']
Out[18]:
a b
1 2 foo
2 3 fat