Polars Python v2.1.0:禁止字符串与数值混合算术,新增 Iceberg 与递归 CTE
Python Polars 2.1.0
推荐理由
v2.1.0 引入了破坏性变更(禁止字符串与数值混合算术),直接打断现有代码用法。依赖 Polars 进行数据清洗的开发者必须检查并修复相关逻辑,建议升级前先行验证。
💥 Breaking changes
💥 破坏性变更
- Disallow mixed string <=> numeric arithmetic in eager (#30071)
- 禁止在 eager 模式下混合字符串与数值算术运算 (#30071)
🚀 Performance improvements
🚀 性能改进
- Limit the memory of buckets sorted ahead in the sort flush (#30297)
- Make file readers wait for spills while over the memory budget (#30296)
- Count unspilled frames in the memory estimate right away (#30295)
- Simplify more boolean expressions and drop redundant null checks (#30293)
- Wait for spills while over the out-of-core memory budget (#30294)
- Lower the default out-of-core prefetch fraction to 0.5 (#30292)
- Aggregate unique and n_unique in the streaming group-by itself (#30281)
- Return freed memory to the OS right away while out-of-core data is spilled (#30280)
- Gather List(Array) and Array columns without per-row slices (#30278)
- Evaluate the streaming window node out of core (#30282)
- Avoid deep copies when building a DataFrame from flat dataclasses (#30275)
- Sort the window partitions by each order key instead of their row encoding (#30277)
- Scan the haystack for a single needle in is_in (#30276)
- Prefer fixed-width columns when only the row count is needed (#30274)
- Native gather for List arrays (#30019)
- Evaluate windows in filter predicates in the streaming window node (#30272)
- Don't busy-wait in RAYON.block_on (#30259)
- Encode nested Parquet levels directly from the level buffers (#30251)
- Reduce memory of CSV scans on wide rows (#30165)
- Avoid quadratic JSON serialization of nested lists and maps (#30203)
- Skip the gather when exploding lists without nulls (#30234)
- Speed up writing nested Parquet columns (#30245)
- Don't keep whole parquet string dictionaries alive for a few selected rows (#30248)
- Set default spill compression level to 1 (#30237)
- Reuse zstd contexts in compression and avoid memcpys (#30233)
- Remove repeated and scalar ordering keys before the sort rewrites (#30231)
- Remove repeated keys from by's (#30095)
- Keep only one guessed unique key per join order leaf (#30191)
- Don't let extra join keys shrink an estimate once one key is unique (#30190)
- Reduce binary size of asof join with by keys (#30192)
- Reduce binary size of SQL visitors and parallel group-by collect (#30171)
- Push as-of join key filters to the right input (#30123)
- Drop null as-of right keys with a parallel filter before the join node (#30125)
- Keep as-of nearest join state small (#30126)
- Explode lists in group_by aggregations without a per-group apply (#30020)
- Streaming OOC group-by with shuffles (#29911)
- Drop scalar ordering keys in the optimizer (#30063)
- Merge union inputs that scan files of the same kind into one multi-file scan (#30056)
- Use the streaming scalar window for std, var and combined reductions in over (#30066)
- Limit the bytes of local CSV and NDJSON files read at once in multi-file scans (#30055)
- Check the matched flag of join keys in the table entry before the bitset (#30067)
- Track matched build rows of all join tables in a bitset (#30050)
- Add dedicated list gather kernels (#30049)
- Emit unmatched build rows of single-key joins in row order (#30037)
- Use TopK for sorts sliced at a nonzero offset (#29989)
- Add constant folding for more datetime ops (#30016)
- Rewrite the sum of a column plus a literal to a sum and a count of the column (#30011)
- Push predicates through order-keeping columns (#30007)
- Fix dead early exit in coalesce (#30013)
- Count distinct non-null values in SQL with one group-by in the streaming engine (#30009)
- Skip parquet row groups with the running top-k threshold (#30006)
- Keep decompressed plain string pages as the string data buffer (#29984)
- Fix some in-memory filter regressions (#29988)
- Decompress snappy and zstd parquet pages without zeroing the buffer (#29980)
- Speed up str.len_chars (#29972)
- Speed up str.replace for patterns that end in .*$ (#29971)
- Use the Parquet string prefilter for literal str.contains and SQL LIKE (#29953)
- Keep single-chunk output when filtering wide frames in parallel (#29847)
- Add dedicated list slice kernels (#29938)
- Principled execution order of accumulating streaming nodes (#29933)
- Huge speedup creating wide Struct data (#29813)
- Speed up arg_min and arg_max (especially on data with nulls) (#29849)
- Huge reduction in from_rows and from_dicts memory usage during nested value conversion (#29739)
- Safely push down nested struct field filters to Iceberg (#29665)
- Compare Parquet dictionaries of Categorical and Enum columns as strings for == and is_in (#29885)
- Filter Categorical and Enum Parquet columns while decoding (#29882)
- Rewrite sort().first() to min() and single-key sort_by().first() to min_by() (#29860)
- Decode fixed-length binary Parquet decimals directly into i128 (#29866)
- Look up each dictionary value once when importing Arrow dictionaries as Categorical (#29865)
- Reduce requests and raise concurrency for cloud CSV scans (#29863)
- Reduce requests and raise concurrency for cloud NDJSON scans (#29857)
- Track sortedness through joins (#29852)
- Keep sortedness through widening numeric casts (#29851)
- Rewrite sort_by().first() to min_by and limit sorts read with head() (#29831)
- Cache parsed Iceberg metadata for metadata-path scans (#29791)
- Drop memory when Done in streaming asof_join/is_first_distinct (#29783)
- Drop scalar sort_by keys in the optimizer (#29812)
- Parallel CSV chunk analysis and pread default (#29818)
- Hash inline binview values directly from their view (#29820)
- Use iceberg statistics (#29798)
- Reuse Iceberg catalog and cache REST catalog scans (#29790)
- Preserve sortedness of computed join keys (#29782)
- TopK was holding onto too much data (#29784)
- Write CSV temporal values straight into the buffer (#29778)
- Parse strftime format once and reuse buffer in regex replace (#29777)
- Reduce needless allocations in various kernels (#29775)
- Cache http object store (#29757)
- Fetch each record batch group in its own task (#29755)
- 限制排序刷新中预先排序的桶的内存使用 (#30297)
- 当超出内存预算时,使文件读取器等待溢出操作 (#30296)
- 立即在内存估算中计入未溢出的帧 (#30295)
- 简化更多布尔表达式并移除冗余的空值检查 (#30293)
- 当超出核心外内存预算时,等待溢出操作 (#30294)
- 将默认的核心外预取比例降低至 0.5 (#30292)
- 在流式分组聚合内部直接聚合 unique 和 n_unique (#30281)
- 当核心外数据正在溢出时,立即向操作系统归还已释放的内存 (#30280)
- 无需逐行切片即可收集 List(Array) 和 Array 列 (#30278)
- 在核心外评估流式窗口节点 (#30282)
- 从扁平数据类构建 DataFrame 时避免深层拷贝 (#30275)
- 按每个排序键对窗口分区进行排序,而非按其行编码排序 (#30277)
- 在 is_in 操作中针对单个目标扫描 haystack (#30276)
- 当仅需行数时,优先使用固定宽度列 (#30274)
- List 数组的原生 gather 操作 (#30019)
- 在流式窗口节点的过滤谓词中评估窗口函数 (#30272)
- 避免在 RAYON.block_on 中进行忙等待 (#30259)
- 直接从层级缓冲区对嵌套 Parquet 层级进行编码 (#30251)
- 减少宽行 CSV 扫描的内存占用 (#30165)
- 避免嵌套列表和映射的二元 JSON 序列化 (#30203)
- 在展开不含空值的列表时跳过 gather 操作 (#30234)
- 加速嵌套 Parquet 列的写入 (#30245)
- 不要为少数选定行保留整个 parquet 字符串字典 (#30248)
- 将默认溢出压缩级别设置为 1 (#30237)
- 在压缩中重用 zstd 上下文并避免 memcpy (#30233)
- 在排序重写之前移除重复和标量排序键 (#30231)
- 从 by 子句中移除重复键 (#30095)
- 每个连接顺序叶节点仅保留一个猜测的唯一键 (#30191)
- 一旦某个键是唯一的,不要让额外的连接键缩小估计值 (#30190)
- 减小带有 by 键的 asof 连接的二进制大小 (#30192)
- 减小 SQL 访问者和并行 group-by 收集的二进制大小 (#30171)
- 将 as-of 连接键过滤器推送到右侧输入 (#30123)
- 在连接节点之前使用并行过滤器丢弃 null as-of 右键 (#30125)
- 保持 as-of 最近连接状态较小 (#30126)
- 在不进行逐组应用的情况下展开 group_by 聚合中的列表 (#30020)
- 带有 shuffle 的流式 OOC group-by (#29911)
- 在优化器中移除标量排序键 (#30063)
- 合并扫描同类文件的 union 输入为一个多文件扫描 (#30056)
- 在 over 窗口中使用流式标量窗口进行 std、var 和组合归约 (#30066)
- 限制多文件扫描中一次性读取的本地 CSV 和 NDJSON 文件的字节数 (#30055)
- 在位集之前检查表条目中连接键的匹配标志 (#30067)
- 在位集中跟踪所有连接表的匹配构建行 (#30050)
- 添加专用的列表收集内核 (#30049)
- 按行顺序输出单键连接的不匹配构建行 (#30037)
- 对非零偏移量处的切片排序使用 TopK (#29989)
- 为更多日期时间操作添加常量折叠 (#30016)
- 将列与字面量的求和重写为列的求和与计数 (#30011)
- 通过保持顺序的列推送谓词 (#30007)
- 修复 coalesce 中的死早期退出问题 (#30013)
- 在流式引擎中,对具有单个分组依据的 SQL 计算非空值的 distinct 数量 (#30009)
- 使用运行时的 top-k 阈值跳过 parquet 行组 (#30006)
- 将解压后的纯文本页保留为字符串数据缓冲区 (#29984)
- 修复一些内存过滤回归问题 (#29988)
- 在不清零缓冲区的情况下解压 snappy 和 zstd parquet 页面 (#29980)
- 加速 str.len_chars (#29972)
- 加速以 .*$ 结尾的模式下的 str.replace (#29971)
- 对字面量 str.contains 和 SQL LIKE 使用 Parquet 字符串预过滤器 (#29953)
- 在并行过滤宽帧时保持单块输出 (#29847)
- 添加专用的列表切片内核 (#29938)
- 累积流式节点的原则性执行顺序 (#29933)
- 创建宽 Struct 数据的速度大幅提升 (#29813)
- 加速 arg_min 和 arg_max(特别是在包含 null 值的数据上)(#29849)
- 在嵌套值转换期间,from_rows 和 from_dicts 的内存使用量大幅减少 (#29739)
- 安全地将嵌套 struct 字段过滤器下推到 Iceberg (#29665)
- 将分类和枚举列的 Parquet 字典作为字符串进行比较以用于 == 和 is_in (#29885)
- 在解码过程中过滤分类和枚举 Parquet 列 (#29882)
- 将 sort().first() 重写为 min(),将单键 sort_by().first() 重写为 min_by() (#29860)
- 直接将固定长度二进制 Parquet 小数解码为 i128 (#29866)
- 在将 Arrow 字典导入为 Categorical 时,每个字典值仅查找一次 (#29865)
- 减少请求并提高云 CSV 扫描的并发度 (#29863)
- 减少请求并提高云 NDJSON 扫描的并发度 (#29857)
- 通过连接跟踪有序性 (#29852)
- 在拓宽数值转换时保持有序性 (#29851)
- 将 sort_by().first() 重写为 min_by,并使用 head() 限制读取排序 (#29831)
- 为元数据路径扫描缓存解析后的 Iceberg 元数据 (#29791)
- 在流式 asof_join/is_first_distinct 完成时释放内存 (#29783)
- 在优化器中丢弃标量 sort_by 键 (#29812)
- 并行 CSV 块分析与预读默认设置 (#29818)
- 直接从视图哈希内联 binview 值 (#29820)
- 使用 Iceberg 统计信息 (#29798)
- 重用 Iceberg 目录并缓存 REST 目录扫描 (#29790)
- 保留计算连接键的有序性 (#29782)
- TopK 保留了过多数据 (#29784)
- 将 CSV 时间值直接写入缓冲区 (#29778)
- 在正则替换中仅解析一次 strftime 格式并重用缓冲区 (#29777)
- 减少各种内核中的不必要分配 (#29775)
- 缓存 HTTP 对象存储 (#29757)
- 在每个独立任务中获取每个记录批次组 (#29755)
✨ Enhancements
✨ 增强功能
- Support SQL CREATE TABLE with column definitions in attached Iceberg catalogs (#30260)
- Support SQL CREATE [OR REPLACE] TEMP TABLE (#30256)
- Support recursive SQL CTEs (#30188)
- Writing encrypted Parquet files (#29905)
- Support SQL DROP TABLE [PURGE] on tables of attached catalogs (#30247)
- Add conversion to/from masked numpy arrays (#30232)
- Add overwrite_filter and dynamic partition overwrite to sink_iceberg (#29909)
- Support SQL JOIN ... ON subqueries that read only one input (#30206)
- Support full joins in join_where (#30169)
- Expose fused and nested loop join predicates in the IR visitor (#30176)
- Support LIMIT 1 in correlated SQL scalar subqueries (#30168)
- Support SQL WITH RECURSIVE when no CTE reads itself (#30166)
- Support correlated IN and EXISTS that read both inputs of a SQL join in ON (#30159)
- Support CURRENT_DATE, CURRENT_TIME and CURRENT_TIMESTAMP in SQL (#30144)
- Allow reinterpret between Int128 and Decimal (#30133)
- Add Expr.truncdiv for division rounding toward zero (#30138)
- Support uncorrelated subqueries in SQL JOIN ... ON (#30141)
- Support correlated subqueries in SQL JOIN ... ON and correlated scalar subqueries without an aggregate (#30131)
- Support sinking to Iceberg table with bucket partitioned field (#30091)
- Add create_namespace_if_not_exists to sink_iceberg (#30087)
- Attach Iceberg catalogs to SQLContext via register_catalog (#30113)
- Support OOC kill fraction (#30104)
- Support qualified table names in SQL (#29963)
- Reverse node for streaming engine (#29259)
- Add pl.delete_iceberg (#30032)
- Support named options in SQL read_ipc table function (#30054)
- Support named options in SQL read_parquet table function (#29998)
- Add experimental geoparquet read/write (#29987)
- Accept a list of paths in SQL read_* table functions (#30047)
- Add SQL read_ndjson table function with named options (#29954)
- 支持在附加的 Iceberg 目录中使用列定义的 SQL CREATE TABLE (#30260)
- 支持 SQL CREATE [OR REPLACE] TEMP TABLE (#30256)
- 支持递归 SQL CTEs (#30188)
- 写入加密的 Parquet 文件 (#29905)
- 支持在附加目录的表上执行 SQL DROP TABLE [PURGE] (#30247)
- 添加对掩码 numpy 数组的转换功能 (#30232)
- 为 sink_iceberg 添加 overwrite_filter 和动态分区覆盖功能 (#29909)
- 支持仅读取一个输入的 SQL JOIN ... ON 子查询 (#30206)
- 在 join_where 中支持全连接 (#30169)
- 在 IR 访问器中暴露融合和嵌套循环连接谓词 (#30176)
- 在相关 SQL 标量子查询中支持 LIMIT 1 (#30168)
- 当 CTE 不引用自身时,支持 SQL WITH RECURSIVE (#30166)
- 支持在 ON 子句中读取 SQL 连接两个输入的相关 IN 和 EXISTS (#30159)
- 在 SQL 中支持 CURRENT_DATE、CURRENT_TIME 和 CURRENT_TIMESTAMP (#30144)
- 允许 Int128 与 Decimal 之间的重新解释 (#30133)
- 添加 Expr.truncdiv 用于向零取整的除法运算 (#30138)
- 在 SQL JOIN ... ON 中支持非相关子查询 (#30141)
- 在 SQL JOIN ... ON 和相关标量子查询(无聚合)中支持相关子查询 (#30131)
- 支持写入具有桶分区字段的 Iceberg 表 (#30091)
- 为 sink_iceberg 添加 create_namespace_if_not_exists (#30087)
- 通过 register_catalog 将 Iceberg 目录附加到 SQLContext (#30113)
- 支持 OOC kill fraction (#30104)
- 在 SQL 中支持限定表名 (#29963)
- 为流式引擎添加反向节点 (#29259)
- 添加 pl.delete_iceberg (#30032)
- 在 SQL read_ipc 表函数中支持命名选项 (#30054)
- 在 SQL read_parquet 表函数中支持命名选项 (#29998)
- 添加实验性的 geoparquet 读写功能 (#29987)
- 在 SQL read_* 表函数中接受路径列表 (#30047)
- 添加带有命名选项的 SQL read_ndjson 表函数 (#29954)
更进一步:量化金融体系
看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力