三过滤数据

Posted 5250

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三过滤数据相关的知识,希望对你有一定的参考价值。

数据表中的数据一般都是非常大,我们一般只需要查询特定的数据

3.1 where单一子句
>>> select * from trade WHERE trade_date=\'20230313\'; #匹配查询
>>> select user_id,product_id,order_id form trade WHERE user_id=\'tom\'; #匹配查询特定列
>>> select * from trade WHERE qty <> 50000; #不匹配查询
>>> select * from trade WHERE price between 10.00 and 105.00; #范围查询,还有范围:in
>>> select * from trade WHERE ext_fields IS NULL; #空值检查
where子句操作符:=,<>,!=,>,>=,<,<=, between...and...

3.2 where多子句组合
多个子句组合需要使用逻辑操作符and, or连接(and的优先级高于or);当多个子句组合时,先执行and,再执行or.
>>> select * from trade where user_id=\'tom\' AND trade_date>=20230121;
>>> select * from trade where trade_date=20230101 OR trade_date=20230202;
>>> select * from trade where user_id not in (\'tom\',\'bill\');
>>> select * from trade where trade_date=20230101 OR trade_date=20230202 AND user_id=\'tom\';
返回结果:满足trade_date=20230101的所有数据 + 满足trade_date=20230202 AND user_id=\'tom\'的所有数据

3.3 通配符过滤
like操作符,模糊搜索。 与%连用。 %表示任意字符出现任意次数; _表示任意字符出现一次。
>>> select * from trade where product_id like \'jet%\'; #查找以jet开头的所有产品
>>> select * from trade where product_id like \'%com\'; #查找以jet结尾的所有产品
>>> select * from trade where product_id like \'j%com\'; #查找以j开头,以jet结尾的所有产品
>>> select * from trade where product_id like \'jet_\'; #查找以jet开头的所有产品(产品名称长度4个字符)

3.4 过滤后排序
先过滤,再排序
>>> select * from trade where product_id like \'jet%\' order by trade_date DESC;

动态过滤熊猫数据框

【中文标题】动态过滤熊猫数据框【英文标题】:Dynamically filtering a pandas dataframe 【发布时间】:2018-02-06 02:19:36 【问题描述】:

我正在尝试使用三列的阈值过滤熊猫数据框

import pandas as pd
df = pd.DataFrame("A" : [6, 2, 10, -5, 3],
                   "B" : [2, 5, 3, 2, 6],
                   "C" : [-5, 2, 1, 8, 2])
df = df.loc[(df.A > 0) & (df.B > 2) & (df.C > -1)].reset_index(drop = True)

df
    A  B  C
0   2  5  2
1  10  3  1
2   3  6  2

但是,我想在一个函数中执行此操作,其中列的名称及其阈值在字典中提供给我。这是我的第一次尝试,效果很好。本质上,我将过滤器放在 cond 变量中并运行它:

df = pd.DataFrame("A" : [6, 2, 10, -5, 3],
                   "B" : [2, 5, 3, 2, 6],
                   "C" : [-5, 2, 1, 8, 2])
limits_dic = "A" : 0, "B" : 2, "C" : -1
cond = "df = df.loc["
for key in limits_dic.keys():
    cond += "(df." + key + " > " + str(limits_dic[key])+ ") & "
cond = cond[:-2] + "].reset_index(drop = True)"
exec(cond)
df
    A  B  C
0   2  5  2
1  10  3  1
2   3  6  2

现在,最后我把所有东西都放在一个函数中,它停止工作(也许exec 函数不喜欢在函数中使用!):

df = pd.DataFrame("A" : [6, 2, 10, -5, 3],
                   "B" : [2, 5, 3, 2, 6],
                   "C" : [-5, 2, 1, 8, 2])
limits_dic = "A" : 0, "B" : 2, "C" : -1
def filtering(df, limits_dic):
    cond = "df = df.loc["
    for key in limits_dic.keys():
        cond += "(df." + key + " > " + str(limits_dic[key])+ ") & "
    cond = cond[:-2] + "].reset_index(drop = True)"
    exec(cond)
    return(df)

df = filtering(df, limits_dic)
df
    A  B  C
0   6  2 -5
1   2  5  2
2  10  3  1
3  -5  2  8
4   3  6  2

我知道exec 函数在函数内部使用时的行为有所不同,但不知道如何解决该问题。另外,我想知道在给定两个输入的情况下,必须有一种更优雅的方法来定义一个函数来进行过滤:1)df 和 2)limits_dic = "A" : 0, "B" : 2, "C" : -1。我将不胜感激。

【问题讨论】:

如果您更改结果的名称(cond = "df2 = df.loc["return(locals()['df2'])),它会起作用。我试图将字典添加到exec 无济于事 如需更多关于pd.eval()系列函数、它们的特性和用例的信息,请访问Dynamic Expression Evaluation in pandas using pd.eval()。 【参考方案1】:

两者都张贴的替代品,可能更pythonic,也可能不是:

import pandas as pd
import operator
from functools import reduce

df = pd.DataFrame("A": [6, 2, 10, -5, 3],
                   "B": [2, 5, 3, 2, 6],
                   "C": [-5, 2, 1, 8, 2])

limits_dic = "A": 0, "B": 2, "C": -1

# equiv to [df['A'] > 0, df['B'] > 2 ...]
loc_elements = [df[key] > val for key, val in limits_dic.items()]

df = df.loc[reduce(operator.and_, loc_elements)]

【讨论】:

【参考方案2】:

如何在不创建字符串和 df.query 的情况下做到这一点:

limits_dic = "A" : 0, "B" : 2, "C" : -1
cond = None

# Build the conjunction one clause at a time 
for key, val in limits_dic.items():
    if cond is None:
        cond = df[key] > val
    else:
        cond = cond & (df[key] > val)

df.loc[cond]

    A  B  C
0   2  5  2
1  10  3  1
2   3  6  2

请注意硬编码的 (&gt;, &amp;) 运算符(因为我想完全按照您的示例进行操作)。

【讨论】:

【参考方案3】:

如果您尝试构建动态查询,有更简单的方法。这是一个使用列表理解和str.join

query = ' & '.join(['>'.format(k, v) for k, v in limits_dic.items()])

或者,将f-strings 与 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()])

请参阅this Stack Overflow post 了解更多信息。


如果您想为查询获取布尔掩码,也可以使用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

字符串数据

如果需要查询使用字符串数据的列,上面的代码需要稍作修改。

考虑(来自this answer的数据):

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() 系列函数、它们的特性和用例的信息,请访问Dynamic Expression Evaluation in pandas using pd.eval()。

【讨论】:

在 f-strings 中,您可以使用上面的简写 k!r,而不是 repr(k)...有助于像上面这样的长表达式。 同一列有多个值如何处理 @Abhis 那应该是什么样子? @cs95 如果我的列名本身有一些运算符,例如C &gt; D,我想比较两个这样的列。我应该在每个列名周围添加双引号,并在单引号中添加整个查询吗? 关于使用“掩码”的那部分回答了我在使用“loc”以避免链式索引时如何将“查询”与选择列子集结合起来的问题。谢谢!【参考方案4】:

@coldspeed 版本的替代方案:

conditions = None
for key, val in limit_dic.items():
    cond = df[key] > val
    if conditions is None:
        conditions = cond
    else:
        conditions = conditions & cond
print(df[conditions])

【讨论】:

谢谢。我找不到一种方法来使接受的答案将引用我的代码中定义的 python 列表的isin 条件结合在一起。

以上是关于三过滤数据的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS 讲解,三 过滤器

〈三〉ElasticSearch的认识:搜索过滤排序

class08_过滤数据

SQL语句检索数据排序及过滤

vue如何自定义过滤器

三Spring Security过滤器链