[英]Iterating through a list to build an OR statement
我有一個函數,該函數需要一個DataFrame並對由OR
連接的特定列執行一系列過濾器。 我只需要一列低於96即可通過過濾器。
這段代碼可以正常工作,但是我想改進該功能,以便能夠向該函數傳遞一個list
,該list
將成為過濾器,而不是將列硬編碼到該函數中。
def remove_never_used_focus(drugs, df):
""" Filters out values above 95 which are
codes for never used or not answered """
df = df[
(df['CAN_060'] < 96) |
# (df['ALC_30'] < 96) |
(df['PS_30'] < 96) |
(df['COC_20'] < 96) |
(df['HAL_20'] < 96) |
(df['MET_20'] < 96) |
(df['XTC_20'] < 96) |
(df['GLU_20'] < 96) |
(df['HER_20'] < 96) |
(df['SAL_20'] < 96)
]
# this produces and `AND` statement I would like and `OR` statement
for drug in drugs:
df = df[(df[drug]) < 96]
display(df)
return df
我想到構建此語句的唯一方法是遍歷list
並逐步構建它。 但是,這將生成一個AND
語句。
使用DataFrame.any
進行測試,以便在過濾的列中每行至少有一個值為True
:
df = pd.DataFrame({
'A':list('abcdef'),
'CAN_060':[400,512,4,5,5,400],
'PS_30':[742,8,9,4,200,300],
'COC_20':[100,3,5,7,100,100],
'E':[5,3,6,9,2,4],
'F':list('aaabbb')
})
print (df)
A CAN_060 PS_30 COC_20 E F
0 a 400 742 100 5 a
1 b 512 8 3 3 a
2 c 4 9 5 6 a
3 d 5 4 7 9 b
4 e 5 200 100 2 b
5 f 400 300 100 4 b
cols = ['CAN_060','PS_30','COC_20']
print ((df[cols] < 96))
CAN_060 PS_30 COC_20
0 False False False
1 False True True
2 True True True
3 True True True
4 True False False
5 False False False
df1 = df[(df[cols] < 96).any(axis=1)]
print (df1)
A CAN_060 PS_30 COC_20 E F
1 b 512 8 3 3 a
2 c 4 9 5 6 a
3 d 5 4 7 9 b
4 e 5 200 100 2 b
#for AND for testing if all values per rows are True
df2 = df[(df[cols] < 96).all(axis=1)]
print (df2)
A CAN_060 PS_30 COC_20 E F
2 c 4 9 5 6 a
3 d 5 4 7 9 b
我認為在您的情況下,您應該嘗試使用pandas.eval函數來連接要執行的操作:
operations = ''
for drug in drugs:
operations = operations + ' | ' + '(df.' + drug + '< 96)'
df = pd.eval(operations)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.