带有AND/OR运算符的PANDA/Numpy Multiple IF语句

cotxawn7  于 2022-11-10  发布在  其他
关注(0)|答案(3)|浏览(126)

我有一个相当复杂的if语句,我想将其作为列添加到我的Pandas数据框中。在过去,我总是使用numpy.select来解决这类问题,但是我不知道如何使用多行的if语句来实现这一点。
我能够在Excel中获得以下内容:

=IF(sum1=3,IF(AND(col1=col2,col2=col3),0,1),IF(sum1=2,IF(OR(col1=col2,col2=col3,col1=col3),0,1),IF(sum1=1,0,1)))

并将其编写为一个常规的多行‘if语句’,只是想知道是否有一种更简洁的方式来表示它。

if df['sum1'] == 3:
  if df['col1'] == df['col2'] and df['col2'] == df['col3']:
    df['verify_col'] = 0
  else:
    df['verify_col'] = 1
elif df['sum1'] == 2:
  if df['col1'] == df['col2'] or df['col2'] == df['col3'] or df['col1'] == df['col3']:
    df['verify_col'] = 0
  else:
    df['verify_col'] = 1
elif df['sum1'] == 1:
  df['verify_col'] = 0
else:
  df['verify_col'] = 1

以下是一些样本数据:

df = pd.DataFrame({
    'col1': ['BMW', 'Mercedes Benz', 'Lamborghini', 'Ferrari', null],
    'col2': ['BMW', 'Mercedes Benz', null, null, 'Tesla'],
    'col3': ['BMW', 'Mercedes', 'Lamborghini', null, 'Tesla_'],
    'sum1': [3, 3, 2, 1, 2]
})

我想要一个具有以下结果的专栏:

'verify_col': [0, 1, 0, 0, 1]

它基本上检查列是否与其中包含值的列匹配,并为每行分配1或0。1表示它们不同,0表示零差异。

mbjcgjjk

mbjcgjjk1#

OR使用numpy.where和链掩码,|表示位OR-如果没有匹配任何条件创建1

m1 = (df['sum1'] == 3)
m2 = (df['col1'] == df['col2']) & (df['col2'] == df['col3'])
m3 = (df['sum1'] == 2)
m4 = (df['col1'] == df['col2']) | (df['col2'] == df['col3']) | (df['col1'] == df['col3'])
m5 = df['sum1'] == 1

df['verify_col'] = np.where((m1 & m2) | (m3 & m4) | m5, 0, 1)

如果需要None,如果不符合任何条件:

df['verify_col'] = np.select([(m1 & m2) | (m3 & m4) | m5,
                              (m1 & ~m2) | (m3 & ~m4) | ~m5], 
                             [0,1], default=None)

print (df)
            col1           col2         col3  sum1  verify_col
0            BMW            BMW          BMW     3           0
1  Mercedes Benz  Mercedes Benz     Mercedes     3           1
2    Lamborghini            NaN  Lamborghini     2           0
3        Ferrari            NaN          NaN     1           0
4            NaN          Tesla       Tesla_     2           1
6jjcrrmo

6jjcrrmo2#

一个选项是使用pyjanitor中的case_When:


# pip install pyjanitor

import pandas as pd
import janitor

(df
.case_when(

# condition, result

df.sum1.eq(3) & df.col1.eq(df.col2) & df.col2.eq(df.col3), 0,
df.sum1.eq(3), 1,
df.sum1.eq(2) & (df.col1.eq(df.col2) | df.col2.eq(df.col3) | df.col1.eq(df.col3)), 0,
df.sum1.eq(2), 1,
df.sum1.eq(1), 0,
1, # default
column_name='verify_col')
)

            col1           col2         col3  sum1  verify_col
0            BMW            BMW          BMW     3           0
1  Mercedes Benz  Mercedes Benz     Mercedes     3           1
2    Lamborghini           None  Lamborghini     2           0
3        Ferrari           None         None     1           0
4           None          Tesla       Tesla_     2           1

当然,您可以使用np.select执行此操作:

conditions = [df.sum1.eq(3) & df.col1.eq(df.col2) & df.col2.eq(df.col3), 
              df.sum1.eq(3), 
              df.sum1.eq(2) & (df.col1.eq(df.col2) | df.col2.eq(df.col3) | 
              df.col1.eq(df.col3)), 
              df.sum1.eq(2), 
              df.sum1.eq(1)]

results = [0,1,0,1,0]

outcome = np.select(conditions, results, default=1)
df.assign(verify_col = outcome)

            col1           col2         col3  sum1  verify_col
0            BMW            BMW          BMW     3           0
1  Mercedes Benz  Mercedes Benz     Mercedes     3           1
2    Lamborghini           None  Lamborghini     2           0
3        Ferrari           None         None     1           0
4           None          Tesla       Tesla_     2           1
hjqgdpho

hjqgdpho3#

df['verify_col'] = (~(((df["col1"] == df["col2"]) | df["col1"].isna() | df["col2"].isna()) & ((df["col2"] == df["col3"]) | df["col2"].isna() | df["col3"].isna()))).astype(int)

相关问题