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 是一个列表 '[]' 将它更改为元组 '()' 没有改变任何东西。
任何帮助深表感谢。
我假设您想要查询 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(',')