SQLite/Pandas/Python 筛选任意列恰好含3个指定值的行
实现方案
SQLite 原生查询实现
不需要枚举所有三列组合,直接利用SQLite布尔表达式返回1/0的特性,对20个数值列的匹配结果求和,判断总和等于3即可,完整SQL如下:
SELECT * FROM numbers WHERE (N1 IN (10,20,30,40,50,60,70,80)) + (N2 IN (10,20,30,40,50,60,70,80)) + (N3 IN (10,20,30,40,50,60,70,80)) + (N4 IN (10,20,30,40,50,60,70,80)) + (N5 IN (10,20,30,40,50,60,70,80)) + (N6 IN (10,20,30,40,50,60,70,80)) + (N7 IN (10,20,30,40,50,60,70,80)) + (N8 IN (10,20,30,40,50,60,70,80)) + (N9 IN (10,20,30,40,50,60,70,80)) + (N10 IN (10,20,30,40,50,60,70,80)) + (N11 IN (10,20,30,40,50,60,70,80)) + (N12 IN (10,20,30,40,50,60,70,80)) + (N13 IN (10,20,30,40,50,60,70,80)) + (N14 IN (10,20,30,40,50,60,70,80)) + (N15 IN (10,20,30,40,50,60,70,80)) + (N16 IN (10,20,30,40,50,60,70,80)) + (N17 IN (10,20,30,40,50,60,70,80)) + (N18 IN (10,20,30,40,50,60,70,80)) + (N19 IN (10,20,30,40,50,60,70,80)) + (N20 IN (10,20,30,40,50,60,70,80)) = 3;
- 实现逻辑:SQLite中条件判断成立时返回整数
1,不成立返回0,把20列的判断结果直接相加,得到的就是该行命中目标值的总个数,直接判断总和等于3就满足“恰好3个匹配”的要求。 - 成本说明:不用写复杂的枚举逻辑,把N1到N20的列名复制后批量拼接判断条件即可,全程耗时不超过1分钟,比枚举C(20,3)=1140种组合的方案简洁太多。
- 性能表现:13500行数据跑这个查询是毫秒级,没有额外性能损耗。
- 扩展能力:后续如果需要调整匹配数量,直接把最后的
=3改成对应数字即可;如果需要更换目标值集合,统一替换IN括号里的数值就行,维护成本极低。
Pandas 实现
用Pandas的矢量化判断做逐行统计,不需要写循环,代码简洁性能高:
import sqlite3 import pandas as pd # 连接数据库读取全表数据 conn = sqlite3.connect("你的数据库文件实际路径.db") df = pd.read_sql("SELECT * FROM numbers", conn) conn.close() # 配置匹配参数 target_values = {10, 20, 30, 40, 50, 60, 70, 80} # 待匹配的目标值集合 required_match_cnt = 3 # 要求恰好命中的数量 # 提取所有存储数值的N列 n_cols = [f"N{i}" for i in range(1, 21)] # 矢量化判断每个值是否在目标集合中,按行求和得到每行命中数,筛选符合数量要求的行 match_result = df[n_cols].isin(target_values).sum(axis=1) == required_match_cnt filtered_df = df[match_result] # 后续如果需要导出结果或者存回数据库,打开对应注释即可 # filtered_df.to_csv("筛选结果.csv", index=False) # filtered_df.to_sql("filtered_numbers", conn, if_exists="replace", index=False)
- 实现逻辑:
isin方法是Pandas底层实现的矢量化运算,会批量判断所有数值是否属于目标集合,按行求和后就能得到每行的命中目标值个数,直接筛选等于要求数量的行即可。 - 性能表现:万级数据可以瞬间出结果,就算数据量涨到十万、百万级,性能也远好于逐行apply或者循环判断的写法。
- 扩展能力:和SQL方案一样,只需要修改
target_values和required_match_cnt两个参数,就能适配不同的匹配需求,核心逻辑不需要改动。
两种方案都完全满足“目标值出现在任意列、恰好匹配3个”的要求,没有逻辑漏洞,也不需要冗余的枚举判断。
内容的提问来源于stack exchange,提问作者YoYoYo
相关产品推荐
相关产品推荐

