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

如何在Polars-Rust中将JSON字符串列导出为JSON数组文件

问题描述

我有一个包含合法JSON字符串列的DataFrame,希望将该列内容转换为每行对应一个对象的JSON数组文件,寻求合适的实现方案。

在Python中我用Polars实现的代码如下:

import polars as pl
import json

df = df.with_columns(
    pl.col("my_str_column").str.json_decode()
)

column_as_list = df.select(pl.col("my_str_column")).to_series().to_list()

with open('target_file.json', 'w+') as w:
    w.write(json.dumps([ob for ob in column_as_list]))

这个方案能正常运行但并非最优。现在想转换成Polars-Rust实现,目前完成了将列转为struct类型的步骤:

df = df.lazy().with_column(
        col("my_str_column").str().json_decode(None, Some(100))
    ).collect()?;

之后我移除了json_decode()保留字符串列,实现了以下可运行的代码,但不确定是否是最优方式,希望得到优化建议:

// hacky way to convert the desired column into a series
let binding = df.select("my_str_column").pop().unwrap(); 
let series_collect: Vec<&str> = binding.str().unwrap().into_no_null_iter().collect();

// Convert input into Vec<Value>, by parsing each string
let elems = series_collect.into_iter()
    .map(serde_json::from_str)
    .collect::<Result<Vec<Value>,_>>()
    .unwrap();

let json_val = Value::Array(elems);

// now write this json_val into disk
let mut path = std::env::current_dir()?;
path.push("target_file.json");

let file = File::create(path)?;
let mut writer = BufWriter::new(file);
serde_json::to_writer(&mut writer, &json_val).unwrap();
writer.flush()?;
优化建议

1. 复用Polars解析结果,避免重复JSON解析

既然已经通过json_decode()将列转为Struct类型,直接基于解析后的Struct序列化,无需先转回字符串再重新解析,减少性能开销:

use polars::prelude::*;
use serde_json::{self, Value};
use std::fs::File;
use std::io::BufWriter;

// 假设已完成json_decode并得到含Struct列的DataFrame
let struct_series = df.column("my_str_column").unwrap();

// 将Struct列序列化为JSON数组
let values: Result<Vec<Value>, _> = struct_series
    .struct_()
    .unwrap()
    .iter()
    .map(|struct_val| serde_json::to_value(struct_val))
    .collect();

let json_array = Value::Array(values.unwrap());

// 写入文件
let path = std::env::current_dir()?.join("target_file.json");
let file = File::create(path)?;
let mut writer = BufWriter::new(file);
serde_json::to_writer(&mut writer, &json_array)?;
writer.flush()?;

2. 流式写入降低内存占用

如果处理大数据集,避免把所有JSON对象加载到内存,改用流式写入:手动拼接JSON数组格式,逐个序列化Struct元素写入文件:

use polars::prelude::*;
use serde_json;
use std::fs::File;
use std::io::{BufWriter, Write};

// 假设已完成json_decode的DataFrame
let struct_series = df.column("my_str_column").unwrap();
let struct_iter = struct_series.struct_().unwrap().iter();

let path = std::env::current_dir()?.join("target_file.json");
let file = File::create(path)?;
let mut writer = BufWriter::new(file);

// 写入数组开头
writer.write_all(b"[")?;

let mut first = true;
for struct_val in struct_iter {
    if !first {
        writer.write_all(b",")?;
    }
    first = false;
    // 直接序列化当前Struct到文件
    serde_json::to_writer(&mut writer, struct_val)?;
}

// 写入数组结尾
writer.write_all(b"]")?;
writer.flush()?;

3. 优化错误处理与列获取

  • 替换unwrap()为?传播错误,避免生产环境panic,建议将逻辑封装为返回Result<(), Box<dyn std::error::Error>>的函数;
  • 用df.column("my_str_column").unwrap()替代df.select("my_str_column").pop().unwrap(),避免不必要的DataFrame拷贝。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:54:52