Python:如果其他两列在同一行中包含 'No' 字符串,则从行中删除字符串值

Python: Remove string value from row if two other columns contain 'No' string in same row

我在下面的 pandas 数据框中有以下示例 table。

Col1       Col2        Col3     Col4          Col5
                       No       4/30/2018     No
                       No       4/30/2018     No
Await AIR  7/15/2015   Yes      4/30/2018     No
Await LER  7/15/2015   No       4/30/2018     No
Await TEE  7/15/2015   No       4/30/2018     No

我要实现的逻辑如下: 如果 Col3 是 'No' 并且 Col5 是 'No' 我想删除 Col1 中的字符串(如果它不是空的)并将其设为空。

下面是我想要的输出 table:

Col1       Col2        Col3     Col4          Col5
                       No       4/30/2018     No
                       No       4/30/2018     No
Awaiting   7/15/2015   Yes      4/30/2018     No
           7/15/2015   No       4/30/2018     No
           7/15/2015   No       4/30/2018     No

我想我有 if 语句,但不知道如何编写逻辑的其余部分:

if df_EVENT5_21['shipping_filter'] == 'No' and df_EVENT5_21['shipping_filter_2'] == 'No':
    ...
df['Col1'] = np.where( ((df['Col3 '] == 'No') & (df['Col5'] == 'No']) ), '', df['Col1'])

使用pd.DataFrame.mask

df[['Col1']].mask(df[['Col3', 'Col5']].eq('No').all(1), '')

        Col1
0           
1           
2  Await AIR
3           
4           

我们可以使用 pd.DataFrame.assign

进行流水线处理
df.assign(
    **df[['Col1']].mask(df[['Col3', 'Col5']].eq('No').all(1), '')
)

        Col1       Col2 Col3       Col4 Col5
0                         No  4/30/2018   No
1                         No  4/30/2018   No
2  Await AIR  7/15/2015  Yes  4/30/2018   No
3             7/15/2015   No  4/30/2018   No
4             7/15/2015   No  4/30/2018   No

pd.DataFrame.update

df.update(df[['Col1']].mask(df[['Col3', 'Col5']].eq('No').all(1), ''))
df

        Col1       Col2 Col3       Col4 Col5
0                         No  4/30/2018   No
1                         No  4/30/2018   No
2  Await AIR  7/15/2015  Yes  4/30/2018   No
3             7/15/2015   No  4/30/2018   No
4             7/15/2015   No  4/30/2018   No

或者不用双括号

df.assign(
    Col1=df.Col1.mask(df[['Col3', 'Col5']].eq('No').all(1), '')
)

df.update(df.Col1.mask(df[['Col3', 'Col5']].eq('No').all(1), ''))
df

一种方法是使用 .loc 带掩码的访问器:

df = pd.DataFrame({'Col1': ['', '', 'AWait AIR', 'Await LER', 'Await TEE'],
                   'Col2': ['', '', '7/15/2015', '7/15/2015', '7/15/2015'],
                   'Col3': ['No', 'No', 'Yes', 'No', 'No'],
                   'Col4': ['4/30/2018', '4/30/2018', '4/30/2018', '4/30/2018', '4/30/2018'],
                   'Col5': ['No', 'No', 'No', 'No', 'No']})

df.loc[(df[['Col3', 'Col5']] == 'No').all(axis=1), 'Col1'] = ''

#         Col1       Col2 Col3       Col4 Col5
# 0                         No  4/30/2018   No
# 1                         No  4/30/2018   No
# 2  AWait AIR  7/15/2015  Yes  4/30/2018   No
# 3             7/15/2015   No  4/30/2018   No
# 4             7/15/2015   No  4/30/2018   No

说明

此解决方案的灵感来自 numpy 创建布尔数组的逻辑:

(df[['Col3', 'Col5']].values == 'No').all(axis=1)

# array([ True,  True, False,  True,  True], dtype=bool)