使用字典中的值过滤 pandas 数据框的列和行

Filter a pandas dataframe columns and rows using values from a dict

我需要用字典过滤数据框,该字典以列名为键,值列表为我要过滤的值:

dict_filter = {'A':'high', 'B':'medium', 'C':['bottom', 'high']}
# the dataframe is like
df = pd.DataFrame({'id':[1,2], 'A':['high', 'high'], 'B':['high','medium'],'C':['high','bottom']})

数据框就像

    id      A          B          C   
0   1     'high'     'high'     'high'
1   1     'high'    'medium'    'bottom'

我想按如下方式过滤数据框:

    id      A          B          C   
1   1     'high'    'medium'    'bottom'

我尝试了以下方法,但它不适用于字典的最后一个值是列表的事实

df.loc[(df[list(dict_filter)] == pd.Series(dict_filter )).all(axis=1)]

有什么建议吗?

bool_arr = []
for k, v in dict_filter.items():
    bool_arr.append(df.loc[:, k].isin(pd.Series(v)))
df.loc[pd.concat(bool_arr, axis=1).all(axis=1)]
#    id     A       B       C
# 1   2  high  medium  bottom

解决方案

我们可以使用 isin 创建一个布尔掩码,但在此之前你必须确保 dict_filter 中的所有值都是字符串列表

d = {k: np.atleast_1d(v) for k, v in dict_filter.items()}
df[df[list(d)].isin(d).all(1)]

   id     A       B       C
1   2  high  medium  bottom

您可以使用:

d = {k:v if isinstance (v, list) else [v]
    for k,v in dict_filter.items()}

mask = (df[list(dict_filter)]
 .apply(lambda c: c.isin(d[c.name]))
 .all(1)
 )

df2 = df[mask]

输出:

   id     A       B       C
1   2  high  medium  bottom

One-liner:

filtered = df[df.apply(lambda col: col.isin(pd.Series(dict_filter.get(col.name, [])))).all(axis=1)]

输出:

>>> filtered
       A       B       C
id                      
2   high  medium  bottom