2017-04-01 19 views
4

任意の長さの条件のリストを取得し、すべての条件の間にアンパサンドを配置する関数を使用したいと考えています。以下のコード例。条件リストを使用してPandasのDataFrameをフィルタリングする

df = pd.DataFrame(columns=['Sample', 'DP','GQ', 'AB'], 
     data=[ 
       ['HG_12_34', 200, 35, 0.4], 
       ['HG_12_34_2', 50, 45, 0.9], 
       ['KD_89_9', 76, 67, 0.7], 
       ['KD_98_9_2', 4, 78, 0.02], 
       ['LG_3_45', 90, 3, 0.8], 
       ['LG_3_45_2', 15, 12, 0.9] 
       ]) 


def some_func(df, cond_list): 

    # wrap ampersand between multiple conditions 
    all_conds = ? 

    return df[all_conds] 

cond1 = df['DP'] > 40 
cond2 = df['GQ'] > 40 
cond3 = df['AB'] < 0.4 


some_func(df, [cond1, cond2]) # should return df[cond1 & cond2] 
some_func(df, [cond1, cond3, cond2]) # should return df[cond1 & cond3 & cond2] 

私はこれに助けていただきありがとうございます。

答えて

5

あなたはそのためのfunctools.reduce使用することができます。

from functools import reduce 

def some_func(df, cond_list): 
    return df[reduce(lambda x,y: x&y, cond_list)]

をそれとも、@AryaMcCarthyが言うように、あなたはオペレータパッケージからand_を使用することができます。

from functools import reduce 
from operator import and_ 

def some_func(df, cond_list): 
    return df[reduce(and_, cond_list)]

またはnumpyの持つ - @ayhanが言うように - 持っています論理的かつ還元的である:

from numpy import logical_and 

def some_func(df, cond_list): 
    return df[logical_and.reduce(cond_list)]
すべての3つのバージョンが作り出す0

- あなたのサンプル入力のために - 次の出力:

>>> some_func(df, [cond1, cond2]) 
     Sample DP GQ AB 
1 HG_12_34_2 50 45 0.9 
2  KD_89_9 76 67 0.7 
>>> some_func(df, [cond1, cond2, cond3]) 
Empty DataFrame 
Columns: [Sample, DP, GQ, AB] 
Index: [] 
+0

ではなく、カスタムラムダの 'operator.and_'を使用するようにしても良いかもしれません。 –

+0

@AryaMcCarthy:ええ、それは確かにもっときれいです。 –

+2

または、numpyから: 'np.logical_and.reduce([cond1、cond2、cond3])' – ayhan

関連する問題