Перебор списка для построения оператора OR - PullRequest
0 голосов
/ 23 мая 2019

У меня есть функция, которая принимает DataFrame и выполняет серию фильтров для определенных столбцов, к которым присоединяется OR.Мне нужен только один столбец, чтобы быть ниже 96, чтобы пройти фильтр.

Этот код работает нормально, но я хотел бы улучшить функцию, чтобы она могла передавать функцию 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.

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Используйте 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
0 голосов
/ 23 мая 2019

Я думаю, что в вашем случае вы должны попробовать функцию pandas.eval для объединения операций, которые вы хотите сделать:

operations = ''

for drug in drugs:
        operations = operations + ' | ' + '(df.' + drug + '< 96)'

df = pd.eval(operations)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...