You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Polars将字典格式字符串列拆分为多列?

问题分析与解决方案

报错原因解析

  1. apply(ast.literal_eval) 报错原因:
    Polars的apply是逐行执行的Python UDF,本身效率极低,且若ast.literal_eval解析后的字典存在隐性类型不一致(比如某键的值多数是整数,但个别行是字符串格式的数字),Polars因无法统一列类型,会抛出ComputeError: got mixed dtypes while constructing List Series。

  2. ndjson相关报错原因:

  • read_json直接加载3.2GB数据导致服务器崩溃,是因为它会一次性将全量数据载入内存,触发内存不足。
  • scan_ndjson报错是因为你的数据并非标准ndjson格式(每行一个JSON对象),而是CSV字符串字段存储JSON,扫描时识别到的是字符串而非JSON对象,触发类型不匹配错误。

Polars正确实现方法

方法1:内置JSON解析+结构体展开(推荐,性能最优)

用Polars原生矢量化函数解析JSON字符串为结构体,再展开成多列,完全绕开Python UDF的性能瓶颈:

import polars as pl

# 读取CSV,保留_source为字符串类型
df = pl.read_csv("your_file.csv")

# 1. 将字符串解析为Polars结构体(Struct)
df = df.with_columns(
    pl.col("_source").str.json_parse().alias("source_struct")
)

# 2. 展开结构体为独立列,同时移除原_source列
df = df.drop("_source").unnest("source_struct")

若存在少量类型不一致的情况,可手动指定结构体类型强制统一:

# 假设_source字典的键为id、name、score,对应类型分别为整数、字符串、浮点数
struct_schema = pl.Struct({
    "id": pl.Int64,
    "name": pl.Utf8,
    "score": pl.Float64
})

df = pl.read_csv("your_file.csv").with_columns(
    pl.col("_source").str.json_parse().cast(struct_schema).alias("source_struct")
).unnest("source_struct")

方法2:转标准ndjson流式处理(适合重复使用场景)

先将CSV中的_source字段提取为标准ndjson格式,再用流式API处理避免内存过载:

import polars as pl

# 流式读取CSV,仅提取_source列并输出为ndjson
(
    pl.scan_csv("your_file.csv")
    .select("_source")
    .write_ndjson("converted.ndjson")
)

# 流式读取ndjson并加载为DataFrame
df = pl.scan_ndjson("converted.ndjson").collect()

性能优化提示

  • 永远优先使用Polars的矢量化函数(如str.json_parse)替代Python UDF(apply),后者会完全绕开Polars的优化引擎,性能暴跌。
  • 大文件处理必须用流式API(scan_csv/scan_ndjson),分块加载数据,避免一次性占用大量内存。

内容的提问来源于stack exchange,提问作者ashtonjesse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 09:13:33