如何基于多列值对列表高效过滤Polars DataFrame?
高效实现Polars DataFrame按指定值对过滤(行级集合差)
直接上最优方案:用Polars的anti_join方法,这是专门实现行级集合差的高效操作,完全替代低效的循环过滤。
完整代码示例
import polars as pl # 原DataFrame df = pl.DataFrame( { "foo": [1, 1, 2, 2, 3, 3, 4], "bar": [6, 7, 8, 9, 10, 11, 12], "ham": ["a", "b", "c", "d", "e", "f", "b"] } ) # 要移除的 值对列表 pairs = [(1,"b"),(3,"e"),(4,"g")] # 把值对转成Polars DataFrame,列名需和原DataFrame对应 filter_df = pl.DataFrame(pairs, schema=["foo", "ham"]) # 执行anti_join,保留在filter_df中找不到匹配的行 result_df = df.anti_join(filter_df, on=["foo", "ham"]) print(result_df)
输出结果
shape: (4, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ├─────┼─────┼─────┤ │ 1 ┆ 6 ┆ a │ │ 2 ┆ 8 ┆ c │ │ 2 ┆ 9 ┆ d │ │ 3 ┆ 11 ┆ f │ └─────┴─────┴─────┘
为什么这个方法高效?
- 循环过滤的问题:每次迭代都要遍历整个DataFrame并生成新数据集,时间复杂度为O(n*k)(n是原数据行数,k是值对数量),数据量越大性能越差。
anti_join是Polars原生的向量化操作,底层用哈希连接实现,仅需遍历原数据和值对各一次,时间复杂度接近O(n + k),大数据量下性能提升显著。
原理说明
anti_join的作用是:返回左侧DataFrame中,所有在右侧DataFrame的指定连接列上无匹配项的行,正好契合你的需求——移除匹配值对列表中任意一组值的行。即便值对列表规模很大,转成Polars DataFrame的开销也极小,Polars对小数据集的处理效率极高。
内容的提问来源于stack exchange,提问作者pikaft
相关产品推荐
相关产品推荐

