Pandas :替换字符串列值(等于、包含、大小写)

Pandas : Replace string column values (equal, contains, case)

我有如下数据农场。

ID   COUNTRY   GENDER    AGE  V1   V2   V3   V4   V5
1    1    1    53   APPLE     apple     bosck     APPLE123  xApple111t
2    2    2    51   BEKO beko SIMSUNG   SamsungO123    ttBeko111t
3    3    1    24   SAMSUNG   bosch     SEMSUNG   BOSC1123  uuSAMSUNG111t

如果列表中有相同的值或包含特定值,我想替换为np.nan。 我在下面尝试但发生错误。

remove_list = ['APPLE', 'BEKO']

remove_contain_list = ['SUNG', 'bosc']

df.iloc[:,4:].str.replace(remove_list, np.nan, case=False) # exact match & case sensitive
df.iloc[:,4:].str.contains(remove_contain_list, np.nan, case=False) # contain & case sensitive

如何解决这些问题?

您可以通过 DataFrame.stack, get masks for exact and partial matches by Series.isin with lowercase values and Series.str.contains, replace by Series.mask (default value for replace is NaN, so no necessary specify) and last Series.unstack 创建 MultiIndex Series 并返回:

remove_list = ['APPLE', 'BEKO']
remove_contain_list = ['SUNG', 'bosc']

s = df.iloc[:,4:].stack(dropna=False)
m1 = s.str.lower().isin([x.lower() for x in remove_list])
m2 = s.str.contains('|'.join(remove_contain_list), case=False)
s = s.mask(m1 | m2)

df.iloc[:,4:] = s.unstack()
print (df)
   ID  COUNTRY  GENDER  AGE   V1   V2   V3        V4          V5
0   1        1       1   53  NaN  NaN  NaN  APPLE123  xApple111t
1   2        2       2   51  NaN  NaN  NaN       NaN  ttBeko111t
2   3        3       1   24  NaN  NaN  NaN       NaN         NaN

编辑:如果在 Styler.apply 中匹配,您可以将蒙版替换为背景颜色:

def color(x): 
    c1 = 'background-color: yellow'
    c = ''

    remove_list = ['APPLE', 'BEKO']
    remove_contain_list = ['SUNG', 'bosc']

    s = x.iloc[:,4:].stack(dropna=False)
    m1 = s.str.lower().isin([i.lower() for i in remove_list])
    m2 = s.str.contains('|'.join(remove_contain_list), case=False)
    m = m1| m2

    df1 = pd.DataFrame(c, index=x.index, columns=x.columns)
    mask = m.unstack(fill_value=False).reindex(x.columns, fill_value=False, axis=1)   
    df1 = df1.mask(mask, c1)
    return df1

df.style.apply(color,axis=None)