如何用Polars表达式查找DataFrame数组中的连续序列?
用Polars表达式查找行内连续序列
完全可以用Polars原生表达式实现行内连续重复序列的检测,不用依赖map_rows,性能会比Python UDF快很多。
步骤示例
假设你的CSV数据格式如下:
Myname,"1,2,3,4,5,5,5,5",AnotherName
- 读取并转换数据
先把字符串格式的数组列转成Polars的Array类型:
import polars as pl # 读取CSV并指定列名 df = pl.read_csv("your_data.csv", new_columns=["name", "values_str", "other_name"]) # 将字符串拆分并转为固定长度的整数数组 df = df.with_columns( pl.col("values_str") .str.split(",") .cast(pl.Array(pl.Int64, 8)) # 8是你提到的固定长度 .alias("values") )
- 检测连续序列
利用Polars的arr.rle()(运行长度编码)函数,直接获取每个连续值的长度,再计算最大连续长度或者筛选符合条件的行:
# 添加一列,记录每行的最大连续序列长度 df = df.with_columns( pl.col("values") .arr.rle() # 返回形如[{"value": x, "length": n}, ...]的结构体数组 .arr.eval(pl.element().struct.field("length")) # 提取所有连续长度 .arr.max() # 取最大连续长度 .alias("max_consecutive_len") ) # 筛选出最大连续长度>=4的行 filtered_df = df.filter(pl.col("max_consecutive_len") >= 4)
如果需要检测指定值的连续长度,可调整表达式:
# 检测值为5的连续序列是否有>=4的情况 df = df.with_columns( pl.col("values") .arr.rle() .arr.eval( pl.when(pl.element().struct.field("value") == 5) .then(pl.element().struct.field("length")) .otherwise(0) ) .arr.max() >= 4 .alias("has_four_consecutive_fives") )
关于@njit对
map_rows的影响 - 用
@njit装饰UDF确实能提升函数内部的执行速度,因为Numba会把Python代码编译成机器码,避免纯Python解释的开销。 - 但
map_rows本质是逐行调用Python函数,不管有没有@njit,都绕不开Python的调用开销,整体性能远不如Polars原生表达式(表达式是向量化执行,在Rust层处理,无Python overhead)。 - 对于Polars的
Array类型,Numba的支持比List更好,因为Array是固定长度的,内存布局更规整,Numba更容易优化。
内容的提问来源于stack exchange,提问作者AnthonyML
相关产品推荐
相关产品推荐

