如果您尝试构建动态查询,有更简单的方法。这是一个使用列表理解和str.join
:
query = ' & '.join(['{}>{}'.format(k, v) for k, v in limits_dic.items()])
或者,使用f
-使用 python-3.6+ 的字符串,
query = ' & '.join([f'{k}>{v}' for k, v in limits_dic.items()])
print(query)
'A>0 & C>-1 & B>2'
将查询字符串传递给df.query
,它就是为了这个目的:
out = df.query(query)
print(out)
A B C
1 2 5 2
2 10 3 1
4 3 6 2
如果我的列名称有空格或其他奇怪的字符怎么办?
从 pandas 0.25 开始,您可以将列名用反引号括起来,这样就可以了:
query = ' & '.join([f'`{k}`>{v}' for k, v in limits_dic.items()])
See 这个堆栈溢出帖子 https://stackoverflow.com/questions/50697536/pandas-query-function-not-working-with-spaces-in-column-names了解更多。
你也可以使用df.eval
如果您想为查询获取布尔掩码,那么索引就变得很简单:
mask = df.eval(query)
print(mask)
0 False
1 True
2 True
3 False
4 True
dtype: bool
out = df[mask]
print(out)
A B C
1 2 5 2
2 10 3 1
4 3 6 2
字符串数据
如果您需要查询使用字符串数据的列,则上面的代码需要稍作修改。
考虑(数据来自这个答案 https://stackoverflow.com/a/50692578/4909087):
df = pd.DataFrame({'gender':list('MMMFFF'),
'height':[4,5,4,5,5,4],
'age':[70,80,90,40,2,3]})
print (df)
gender height age
0 M 4 70
1 M 5 80
2 M 4 90
3 F 5 40
4 F 5 2
5 F 4 3
以及列、运算符和值的列表:
column = ['height', 'age', 'gender']
equal = ['>', '>', '==']
condition = [1.68, 20, 'F']
这里适当的修改是:
query = ' & '.join(f'{i} {j} {repr(k)}' for i, j, k in zip(column, equal, condition))
df.query(query)
age gender height
3 40 F 5
有关信息pd.eval()
函数系列、其特性和用例,请访问使用 pd.eval() 在 pandas 中进行动态表达式评估 https://stackoverflow.com/questions/53779986/dynamic-expression-evaluation-in-pandas-using-pd-eval.