使用Pandas,我必须重写以dict
:
query = {"height": 175}
键是查询的属性,值可以是标量或可迭代的。
在第一部分中,我检查值是否为not NaN and scalar
。
如果这个条件成立,我用==
符号编写查询表达式,否则如果值为Iterable
,我需要用in
关键字编写表达式。
这是我需要修复的实际代码,以便与Iterables一起工作。
import numpy as np
from collections import Iterable
def query_dict_to_expr(query: dict) -> str:
expr = " and ".join(["{} == {}"
.format(k, v) for k, v in query.items()
if (not np.isnan(v)
and np.isscalar(v))
else "{} in @v".format(k) if isinstance(v, Iterable)
]
)
return expr
但是我的语法与else
语句相对应无效。
答案 0 :(得分:1)
如果我理解正确,您不需要检查类型:
In [47]: query
Out[47]: {'height': 175, 'lst_col': [1, 2, 3]}
In [48]: ' and '.join(['{} == {}'.format(k,v) for k,v in query.items()])
Out[48]: 'height == 175 and lst_col == [1, 2, 3]'
演示:
In [53]: df = pd.DataFrame(np.random.randint(5, size=(5,3)), columns=list('abc'))
In [54]: df
Out[54]:
a b c
0 0 0 3
1 4 2 4
2 2 2 3
3 0 1 0
4 0 4 1
In [55]: query = {"a": 0, 'b':[0,4]}
In [56]: q = ' and '.join(['{} == {}'.format(k,v) for k,v in query.items()])
In [57]: q
Out[57]: 'a == 0 and b == [0, 4]'
In [58]: df.query(q)
Out[58]:
a b c
0 0 0 3
4 0 4 1
答案 1 :(得分:0)
你错位了理解中的if/else
。如果您将if
放在for
之后,例如f(x) for x in iterable if g(x)
,则会过滤迭代的元素(并且不能与else
组合)。相反,您希望保留所有元素,即使用f(x) for x in iterable
f(x)
恰好是三元表达式,即a(x) if c(x) else b(x)
形式。
相反,尝试这样(简化的非numpy示例):
>>> query = {"foo": 42, "bar": [1,2,3]}
>>> " and ".join(["{} == {}".format(k, v)
if not isinstance(v, list)
else "{} in {}".format(k, v)
for k, v in query.items()])
'foo == 42 and bar in [1, 2, 3]'