2017-04-13 7 views
-1

toupper()またはその行に沿ったものを使用して、大文字小文字を無視してdict column_filtersで指定される文字列封じ込めに基づいて複数の列にフィルタを設定する必要があります。辞書を使用して複数の文字列封じ込めフィルタをpandasデータフレームに適用

column_filters = {'COLUMN_1': ['drum', 'gui'], 'COLUMN_2': ['sta', 'kic']} 

df = pd.DataFrame({'COLUMN_1': ['DrumSet', 'GUITAR', 'String', 'Bass', 'Violin'], 
        'COLUMN_2': ['STAND', 'DO', 'KICKSET', 'CAT', 'CELLO'], 
        'COLUMN_3': ['LOSER', 'LOVE', 'LICKING', 'STICK', 'BOLOGNA']) 

COLUMN_FILTERS辞書に基づいてフィルタリングするDATAFRAME:

  COLUMN_1 COLUMN_2 COLUMN_3 
     0 DrumSet  STAND  LOSER 
     1 GUITAR  DO   LOVE 
     2 String  KICKSET  LICKING 
     3 Bass   CAT   STICK 
     4 Violin  CELLO  BOLOGNA 

結果:

COLUMN_1 COLUMN_2  COLUMN_3 
0 DrumSet  STAND  LOSER 
1 GUITAR  DO   LOVE 
2 String  KICKSET  LICKING 
+0

あなたのdfを構築するコードがあなたの投稿と結果と一致しません – EdChum

+0

問題を修正しました。 –

答えて

-1

私はあなたがしてDFをフィルタリングするstr.containsを使用することができ、'|'ですべての文字列を連結することにより、正規表現パターンにdictの値を変換したい:

In [50]: 
for k in column_filters.keys(): 
    column_filters[k] = '|'.join(column_filters[k]) 
column_filters 

Out[50]: 
{'COLUMN_1': 'drum|gui', 'COLUMN_2': 'sta|kic'} 

は今のparam case=Falsestr.containsを使用して使用してフィルタ:

In [51]: 
df.loc[(df['COLUMN_1'].str.contains(column_filters['COLUMN_1'], case=False)) | (df['COLUMN_2'].str.contains(column_filters['COLUMN_2'], case=False))] 

Out[51]: 
    COLUMN_1 COLUMN_2 
0 DrumSet STAND 
1 GUITAR  DO 
2 String KICKSET 

更新

ありOK動的メソッド:

In [68]: 
df[df.apply(lambda x: x.str.contains('|'.join(column_filters[x.name]), case=False)).any(axis=1)] 

Out[68]: 
    COLUMN_1 COLUMN_2 
0 DrumSet STAND 
1 GUITAR  DO 
2 String KICKSET 

私たちは、それが正しく一致していることをブールマスキングなしで見ることができます:

In [69]: 
df.apply(lambda x: x.str.contains('|'.join(column_filters[x.name]), case=False)) 

Out[69]: 
    COLUMN_1 COLUMN_2 
0  True  True 
1  True False 
2 False  True 
3 False False 
4 False False 

アップデート2

をあなたに答えるために、再度質問を修正:

In [75]: 
df[df[list(column_filters.keys())].apply(lambda x: x.str.contains('|'.join(column_filters[x.name]), case=False)).any(axis=1)] 

Out[75]: 
    COLUMN_1 COLUMN_2 COLUMN_3 
0 DrumSet STAND LOSER 
1 GUITAR  DO  LOVE 
2 String KICKSET LICKING 
+0

列の選択範囲は、1から5の異なる列から選択できます。この記事のようにフィルタステートメントを統合する方法はありますか? http://stackoverflow.com/questions/34157811/filter-a-pandas-dataframe-using-values-from-a-dict –

+1

部分一致を探しているため、その解決策は完全一致を探しているため、あなたができることはdfをスタックして単一の比較を行うことです。私は更新を投稿します – EdChum

+1

実際には動作するかもしれませんが、積み重ねれば特定の列比較を探しているので意味的に正しいものではありませんdfを使用して単一の列を作成し、部分一致を検索すると、誤検出が発生する可能性があります。例えば、COLUMN_1にはSTANDまたはKICKSETが含まれています。 – EdChum

関連する問題