我想使用列表中的所有项目创建过滤表达式,以便我可以查询 pandas 数据框。
请使用下面的示例代码:
col = ['A','B']
data = [[0,5],[3,2],[1,9],[2,7]]
df = pd.DataFrame(data, columns=col)
fltr = [('A', 1),
('A', 1, 'B', 5)]
我想在循环中重写下面的代码,这样我就不需要自己编写所有可能的组合:
f = ['{0}>={1}'.format(fltr[0][0], fltr[0][1])]
df.query(f)
f = ['{0}<={1}'.format(fltr[0][0], fltr[0][1])]
df.query(f)
f = ['{0}>={1} and {2}>={3}'.format(fltr[1][0], fltr[1][1], fltr[1][2], fltr[1][3])]
df.query(f)
...
另请注意,我想查询每个表达式的“>=”和“<=”的每个组合
所需的表达方式:
A>=1, A<=1, A>=1 and B>=5, A>=1 and B<=5, A<=1 and B>=5, A<=1 and B<=5
最佳答案
您将需要多个部件才能获得您想要的结果。您需要一个函数将元组拆分为一系列 2 元组。 itertools
包中的 product
函数可以处理创建列、操作和值的组合。然后,您可以对列进行分组,并再次使用产品来获取所有过滤器组合。之后,您可以使用 .join
合并字符串并将过滤器传递给 df.eval
或 df.query
。
import pandas as pd
from itertools import product, groupby
ge, le = '>=', '<='
def split_tuple(tup):
return [tup[i:i+2] for i in range(0, len(tup), 2)]
def create_basic_filters(tup):
f_gen = product(split_tuple(tup), (ge, le))
return [f'{col}{op}{v}' for (col, v), op in f_gen]
def create_filter_groups(basic_filters):
gb = groupby(basic_filters, key=lambda x: x[:x.find('=')-1])
groupings = [tuple(g) for _, g in gb]
return [' & '.join(f) for f in product(*groupings)]
# test the filter creation
fltr = [('A', 1), ('A', 2, 'B', 3), ('A', 1, 'B', 5, 'C', 7),
('A', 0, 'B', 2, 'C', 10, 'D', 15)]
basic_filters = create_basic_filters(fltr[2])
filter_strs = create_filter_groups(basic_filters)
filter_strs
# returns:
['A>=1 & B>=5 & C>=7',
'A>=1 & B>=5 & C<=7',
'A>=1 & B<=5 & C>=7',
'A>=1 & B<=5 & C<=7',
'A<=1 & B>=5 & C>=7',
'A<=1 & B>=5 & C<=7',
'A<=1 & B<=5 & C>=7',
'A<=1 & B<=5 & C<=7']
要实际使用过滤器,我们可以将它们传递给 df.eval
以获取 bool 系列,或者如果您还想对数据帧进行切片,则传递给 df.query
。下面我们使用 for 循环打印每个数据帧的结果切片。
df = pd.DataFrame({'A': [0, 3, 1, 2],
'B': [5, 2, 9, 5],
'C': [3, 7, 11, 5],
'D': [12, 21, 13, 19]})
for f in filter_strs:
print('='*30)
print('Filter =', f)
print(df.query(f))
# prints:
==============================
Filter = A>=1 & B>=5 & C>=7
A B C D
2 1 9 11 13
==============================
Filter = A>=1 & B>=5 & C<=7
A B C D
3 2 5 5 19
==============================
Filter = A>=1 & B<=5 & C>=7
A B C D
1 3 2 7 21
==============================
Filter = A>=1 & B<=5 & C<=7
A B C D
1 3 2 7 21
3 2 5 5 19
==============================
Filter = A<=1 & B>=5 & C>=7
A B C D
2 1 9 11 13
==============================
Filter = A<=1 & B>=5 & C<=7
A B C D
0 0 5 3 12
==============================
Filter = A<=1 & B<=5 & C>=7
Empty DataFrame
Columns: [A, B, C, D]
Index: []
==============================
Filter = A<=1 & B<=5 & C<=7
A B C D
0 0 5 3 12
关于Python使用列表中的项目迭代创建过滤器表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59447437/