使用字典中的值过滤 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
我需要用字典过滤数据框,该字典以列名为键,值列表为我要过滤的值:
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