首页 > 其他分享 >DataFrame RHS语法查询语句

DataFrame RHS语法查询语句

时间:2024-07-26 17:07:02浏览次数:7  
标签:语句 sort res RHS DataFrame cond query eq self

RHS:
https://github.com/acoboh/query-filter-jpa/blob/main/README.md

规则:
查询字段名:查询条件(条件值) 关系符 查询字段名:查询条件(条件值) ...

查询条件有:
‒ eq: 等于
‒ gt: 大于
‒ gte: 大于等于
‒ lt: 小于
‒ lte: 小于等于
‒ ne: 不等于
‒ cn: 包含
‒ ncn: 不包含
‒ re: 正则
‒ sw: 以xxx开头
‒ ew: 以xxx结尾

关系符有:
‒ and: 与
‒ or: 或

排序:
在最后边使用 sort 关键字排序,如果逆序排序,就在字段前加个负号(-)。如:sort(a) 或者 sort(-a)

例:
有如下一个表:
id gene mid e10
1 abc1 23 12
2 test1 35 32
3 abc2 16 21

// 查询 gene = abc1
query = gene:eq(abc1)
得到:
abc1 23 12
虽然这样也能查出来,但是最好用下面这样的命令:
query = id:eq(1)
这样可以提高查询效率

// 查询 mid > 10 且 小于 20
query = mid:gt(10) and mid:lt(20)
得到:
abc2 16 21

// 查询 gene 包含 abc 并按 gene 顺序排序
query = gene:cn(abc) sort(gene)
得到:
abc1 23 12
abc2 16 21

// 查询 gene 包含 abc 并按 gene 逆序排序
query = gene:cn(abc) sort(-gene)
得到:
abc2 16 21
abc1 23 12

【注】不能任意使用空格 只能在两个元素之间使用空格。支持用括号()来表示优先级。

代码

点击查看代码
import re
import pandas as pd
from functools import lru_cache


class QueryManage:
    """Convert the query statement to pandas syntax"""

    # operate map
    OPR_MAP = {
        "eq": lambda x, y: f"['{x}']=={y}",
        "gt": lambda x, y: f"['{x}']>{y}",
        "gte": lambda x, y: f"['{x}']>={y}",
        "lt": lambda x, y: f"['{x}']<{y}",
        "lte": lambda x, y: f"['{x}']<={y}",
        "ne": lambda x, y: f"['{x}']!={y}",
        "cn": lambda x, y: f"['{x}'].str.contains('{y}')",
        "ncn": ("~", lambda x, y: f"['{x}'].str.contains('{y}')"),
        "sw": lambda x, y: f"['{x}'].str.contains(r'^{y}')",
        "ew": lambda x, y: f"['{x}'].str.contains(r'{y}$')",
        # 're': '',
    }

    # relationship map
    RLP_MAP = {"and": "&", "or": "|"}
    # sort
    SORT = lambda x: (
        f"sort_values('{x.replace('-', '')}',ascending=False)"
        if "-" in x
        else f"sort_values('{x}')"
    )
    # pattern filter field
    # PFF = re.compile(f"(?P<field>(\w+)):(?P<operate>(\w+))\((?P<value>(\w+))\)")
    PFF = re.compile(
        f"(?P<leftParen>(^\(*))(?P<field>(\w+)):(?P<operate>(\w+))\((?P<value>(\w+))\)(?P<rightParen>(\)*$))"
    )
    # pattern filter sort
    PFS = re.compile(r"sort\((-*\w+)\)")

    def __init__(self, resource: pd.DataFrame):
        self.resource = resource

    def _validCheck(self, condition: list):
        assert condition[-1] not in self.__class__.RLP_MAP, ValueError("query invalid")

    def _parse(self, condition: list):
        cond = ""
        sort = ""
        switch = False
        for elem in condition:
            switch = not switch
            if switch:
                patRes = self.__class__.PFF.match(elem)
                assert patRes, ValueError("query invalid")
                if patRes.group("leftParen"):
                    cond += "("
                opr = self.__class__.OPR_MAP.get(patRes.group("operate"))
                assert opr, ValueError(f"invalid operate {patRes.group('operate')}")
                if isinstance(opr, tuple):
                    sign, opr_ = opr
                    cond += f"({sign}self.resource{opr_(patRes.group('field'), patRes.group('value'))})"
                else:
                    cond += f"(self.resource{opr(patRes.group('field'), patRes.group('value'))})"
                if patRes.group("rightParen"):
                    cond += ")"
            else:
                rlp = self.__class__.RLP_MAP.get(elem.lower())
                if rlp:
                    cond += rlp
                else:
                    # sort field
                    fs = self.__class__.PFS.findall(elem)
                    assert fs, ValueError("query invalid")
                    sort = self.__class__.SORT(fs[0])
        return cond, sort

    @lru_cache(maxsize=10)
    def query(self, condition: str):
        cond = condition.strip().split(" ")
        self._validCheck(cond)
        cond, sort = self._parse(cond)
        print("cond: ", cond, sort)
        return (
            eval(f"self.resource[{cond}].{sort}")
            if sort
            else eval(f"self.resource[{cond}]")
        )


if __name__ == "__main__":
    df = pd.DataFrame({"a": [1, 2, 3, 4, 5], "b": ["abc", "bcd", "cfg", "adv", "ecf"]})
    qm = QueryManage(df)
    # a==2
    res = qm.query("a:eq(2)")
    print("a==2 :\n", res)

    # a==2 or a==4
    res = qm.query("a:eq(2) or a:eq(4)")
    print("a==2 or a==4 :\n", res)

    # b.contains('b') and a==1
    res = qm.query("b:cn(b) and a:eq(1)")
    print("b.contains('b') and a==1 :\n", res)

    # ~b.contains('a')
    res = qm.query("b:ncn(a)")
    print("~b.contains('a') :\n", res)

    # a>1 sort(-a)
    res = qm.query("a:gt(1) sort(-a)")
    print("a>1 sort(-a) :\n", res)

    # (a ==1 or a==3) and b.contains('f')
    res = qm.query("(a:eq(1) or a:eq(3)) and b:cn(f)")
    print("(a ==1 or a==3) and b.contains('f') :\n", res)

    # a ==1 or a==3 and b.contains('f')
    res = qm.query("a:eq(1) or a:eq(3) and b:cn(f)")
    print("a ==1 or a==3 and b.contains('f') :\n", res)

执行结果
image

image

标签:语句,sort,res,RHS,DataFrame,cond,query,eq,self
From: https://www.cnblogs.com/yimeimanong/p/18325764

相关文章

  • 如何根据 DataFrame 的单列而不是默认计算的总大小在 go.Cone 中分配颜色?
    我正在使用Plotly的go.Cone函数来可视化3D数据。在我的图中,我用位置(x,y,z)和方向(u,v,w)表示圆锥体,其中分量u、v和w对应于每个方向上的力。目前,图中的颜色条默认基于力矢量的总大小(sqrt(u^2+v^2+w^2))。但是,由于我对力进行归一化以保持如果锥体大小......
  • Python基础知识点(1)基本语句
    基本语句1.if语句if表达式:语句块其中,表达式是一个返回True或False的表达式。如果表达式为True,则执行if下面的语句块;如果为False,则跳过语句块执行下面的语句。2.if…else语句if表达式:语句块1else:语句块2其中,表达式是一个返回True或False的表达式。如果......
  • MySQL入门---(一)SQL的DDL语句
    1.管理员身份进入命令行窗口:win+rcmd然后不要直接点,按ctrl+shift+enter管理员模式进去,点确定2.MySQL数据库启动:netstartmysql80停止:netstopmysql803.系统自带的命令行工具执行指令:mysql-uroot-p1.SQL通用语法:2.DDL语句3.表结构查询:4.创建表结构5.表操作--......
  • 006-绕过web检查,传输sql语句的功能
    importorg.apache.commons.text.StringEscapeUtils;/***作用:*实现绕过web检查,传输sql语句的功能**pom:*org.apache.commons:commons-lang3:3.12.0*org.apache.commons:commons-text:1.10.0*/publicclassMain{publicstaticvoidmain(String[]arg......
  • Day4-控制语句
    1.分支语句1.1顺序语句,分支语句,循环语句分支语句if()~else~switch循环语句for()while()~do~while()goto辅助控制语句continuebreakreturn1.2if~else语句的使用if语句概述if(表达式)语句块1else......
  • 基本的DQL语句-单表查询
    一、DQL语言        DQL(DataQueryLanguage数据查询语言)。用途是查询数据库数据,如SELECT语句。是SQL语句中最核心、最重要的语句,也是使用频率最高的语句。其中,可以根据表的结构和关系分为单表查询和多表联查。二、单表查询        针对数据库中的一张......
  • 跳转语句
     一、break语句在for循环中使用break:publicclassBreakExample{ publicstaticvoidmain(String[]args){   for(inti=0;i<10;i++){     if(i==5){       break;     }     System......
  • 如何在 Python 中对多行使用单个 INSERT INTO 语句?
    我目前正在开发一个DiscordPython机器人,我在其中循环遍历ForumTags列表,并为每个对象生成INSERTINTOSQL语句以将数据插入MySQL数据库。但是,我想要通过将所有这些单独的INSERTINTO语句组合到单个查询中来优化我的代码,如下所示:INSERTINTO......
  • 日撸Java三百行(day03:基本if语句)
    文章目录:一、if、then、else1.if语句的第一种格式2.if语句的第二种格式3.if语句的第三种格式二、方法(函数)的调用1.方法定义1.1最简单的方法定义1.2带参数的方法定义1.2.1单个参数的方法定义格式1.2.2多个参数的方法定义格式1.3带返回值的方法定义2.方法的调用2.1......
  • C语言分支语句之if的一些用法
    目录引言C语言结构1.if语句1.1if1.2else2.分支中包含多条语句3.多重选择elseif4.嵌套if5.悬空else/else与if配对问题引言C语言作为一种非常常用的编程语言,具有灵活强大的循环和分支结构。循环结构允许我们重复执行一段代码,而分支结构则允许我们根据条......