如何使用 Pandas 将查询与单个外部变量结合起来

Dav*_*ave 10 python filter dataframe pandas

我正在尝试通过 html 表单(@search)接受由逗号分隔的许多搜索词的可变输入,并查询数据框的 2 列。

每个列查询都独立工作,但我无法让它们以某种和/或方式协同工作。

第一列查询:

filtered = df.query ('`Drug Name` in @search')
Run Code Online (Sandbox Code Playgroud)

第二列查询:

filtered = df.query ('BP.str.contains(@search, na=False)', engine='python')
Run Code Online (Sandbox Code Playgroud)

像这样编辑组合:

filtered = df.query ("('`Drug Name` in @search') and ('BP.str.contains(@search, na=False)', engine='python')")
Run Code Online (Sandbox Code Playgroud)

给出以下错误,突出显示引擎参数中的 python 标识符

SyntaxError: Python 关键字在 numexpr 查询中无效标识符

编辑 2

数据框是从一个 excel 文件中读取的,列有:药物名称(包含单个药物名称)、BP、U&E(具有长描述性文本条目)

搜索词将通过 html 表单输入:

search = request.values.get('searchinput').replace(" ","").split(',')
Run Code Online (Sandbox Code Playgroud)

作为患者可能使用的药物清单,有时会添加与药物使用相关的特定条件。示例用户输入:

卡托普利、扑热息痛、肾病、慢性

我希望对照特定药物名称检查列表,并检查其他列(例如 BP 和 U&E)是否提及任何搜索词。

编辑 3

道歉,但试图实施给出的答案给我带来了一堆错误。我下面的内容是我所追求的 90%,让我搜索两列,包括“BP”的全部内容。但是我只能通过终端搜索一个术语,如果我 # out 并交换收集使用输入的行(从与终端相关的 html 表单中获取),我得到:

类型错误:不可散列的类型:“列表”

@app.route('/', methods=("POST", "GET"))

    def html_table():
        searchterms = []
        #searchterms = request.values.get('searchinput').replace(" ","").split(',')
        searchterms = input("Enter drug...")   
        filtered = df.query('`Drug Name` in @searchterms | BP.str.contains(@searchterms, na=False)', engine='python')
        return render_template('drugsafety.html', tables=[filtered.to_html(classes='data')], titles=['na', 'Drug List'])

<form action="" method="post">
  <p><label for="search">Search</label>
  <input type="text" name="searchinput"></p>        
  <p><input type="submit"></p>
</form>
Run Code Online (Sandbox Code Playgroud)

样本数据

BP 列的内容可能很长、具有描述性和可变性,但示例如下:

每 12 个月 – 每 3 至 6 个月患有 CKD 的患者。

Drug Name         BP                            U&E
Perindopril       Every 12 months               Not needed
Alendronic Acid   Not needed                    Every 12 months
Allopurinol       Whilst titrating - 3 months   Not needed
Run Code Online (Sandbox Code Playgroud)

有了这条线:

searchterms = request.values.get('searchinput')
Run Code Online (Sandbox Code Playgroud)

在 html 表单输出中输入“月”:

1   Perindopril  Every 12 months                Not needed 
14  Allopurinol  Whilst titrating – 3 months    Not needed
Run Code Online (Sandbox Code Playgroud)

都好。

在 html 表单输出中输入“阿仑膦酸”:

13  Alendronic Acid Not needed  Every 12 months
Run Code Online (Sandbox Code Playgroud)

也不错,但输入 'Perindopril, Allopurinol' 没有任何回报。

如果我将行更改为:

searchterms = request.values.get('searchinput').replace(" ","").split(',')
Run Code Online (Sandbox Code Playgroud)

当页面重新加载时,我收到 TypeError: unhashable type: 'list' 。

但是 - 如果我再改变:

filtered = df.query('`Drug Name` in @searchterms | BP.str.contains(@searchterms, na=False)', engine='python')
Run Code Online (Sandbox Code Playgroud)

到:

filtered = df.query('`Drug Name` in @searchterms')
Run Code Online (Sandbox Code Playgroud)

然后,不可散列的类型错误出现并输入“Perindopril, Allopurinol”返回:

1   Perindopril   Every 12 months                   Not needed
14  Allopurinol   Whilst titrating – Every 3 months Not needed
Run Code Online (Sandbox Code Playgroud)

但我现在不再在 BP 列中搜索搜索词。

只是认为这可能是因为 searchterms 是一个列表 '[]' 将它更改为元组 '()' 没有改变任何东西。

任何帮助深表感谢。

Saj*_*hil 2

我假设您想要查询 2 列,并希望在任何查询匹配时返回该行。

在这一行中,问题是 engine=python 位于查询内部。

filtered = df.query ("('`Drug Name` in @search') and ('BP.str.contains(@search, na=False)', engine='python')")
Run Code Online (Sandbox Code Playgroud)

它应该是

df.query("BP.str.contains(@search, na=False)", engine='python')
Run Code Online (Sandbox Code Playgroud)

如果这样做searchterms = request.values.get('searchinput').replace(" ","").split(','),它会将您的字符串转换为单词列表,这将导致Unhashable type list错误,因为 str.contains 需要 str 作为输入。

您可以做的是使用正则表达式在列表中搜索搜索词,它看起来像这样:

df.query("BP.str.contains('|'.join(@search), na=False, regex=True)", engine='python')
Run Code Online (Sandbox Code Playgroud)

它的作用是使用正则表达式搜索所有单个单词。('|'.join(@search)将是“searchterm_1|search_term2|...”,“|”在正则表达式中用于表示或,因此它在 BP 列值中查找 searchterm_1 或 searchterm_2)

要合并两个查询的输出,您可以单独运行它们并将结果连接起来

pd.concat([df.query("`Drug Name` in @search", engine='python'),df.query("BP.str.contains('|'.join(@search), na=False, regex=True)", engine='python')])
Run Code Online (Sandbox Code Playgroud)

此外,任何基于字符串的匹配都将要求您的字符串完美匹配,包括大小写。所以你可以小写数据框和查询中的所有内容。同样,对于空格分隔的单词,这将删除空格。

如果你searchterms = request.values.get('searchinput').replace(" ","").split(',')这样做Every 12 months,它将被转换为“Every12months”。所以你可以删除 .replace() 部分并使用searchterms = request.values.get('searchinput').split(',')