
CSV格式不原生支持嵌套数据结构,当Pandas将含list类型的列(如Seq_1)保存为CSV时,会自动转为字符串表示;读取后需手动解析还原为Python列表,常用ast.literal_eval安全反序列化。
csv格式不原生支持嵌套数据结构,当pandas将含list类型的列(如seq_1)保存为csv时,会自动转为字符串表示;读取后需手动解析还原为python列表,常用ast.literal_eval安全反序列化。
在使用Pandas处理含变长数值序列(如整数或浮点数列表)的结构化数据时,一个常见陷阱是:DataFrame中类型为list的列(例如Seq_1、Seq_2)在调用.to_csv()保存后,再通过.read_csv()读回时,该列元素会退化为字符串(如"[1.5, -2, 3]"),而非原始的list对象。这导致原本可用df.loc[0].Seq_1[0]直接访问首元素的操作失效——此时df.loc[0].Seq_1[0]返回的是字符串的第一个字符(如'['或'1'),引发逻辑错误。
根本原因在于:CSV是纯文本平面格式,无法保留Python对象类型信息;Pandas默认将list序列以str(list)方式序列化写入,而read_csv又将其作为普通字符串加载,未做类型恢复。
✅ 正确做法分两步:
-
写入时无需特殊处理(
to_csv保持默认即可); - 读取后立即对目标列执行安全反序列化:
import pandas as pd
import ast
# 读取CSV
df = pd.read_csv("../data/df.csv", low_memory=False)
# 将字符串形式的列表还原为Python list
df["Seq_1"] = df["Seq_1"].apply(ast.literal_eval)
df["Seq_2"] = df["Seq_2"].apply(ast.literal_eval)
# 验证类型已恢复
print(type(df.loc[0, "Seq_1"])) # <class>
print(df.loc[0, "Seq_1"][0]) # -2.0 或 1(原始数值,非字符串)</class>
⚠️ 注意事项:
- 务必使用
ast.literal_eval(而非eval),它仅解析字面量表达式(list,tuple,dict,int,float,str,bool,None),可有效防止代码注入风险; - 若CSV中存在空值(
NaN),ast.literal_eval会报错,需预先处理:df["Seq_1"] = df["Seq_1"].apply(lambda x: ast.literal_eval(x) if pd.notna(x) else [])
- 对于大规模数据,可考虑使用
json格式替代CSV(如df.to_json(...)+pd.read_json(...)),天然支持嵌套结构,但牺牲了CSV的通用可读性。
总结:CSV不是存储嵌套结构的理想格式。若业务强依赖列表列,建议优先选用parquet或feather等支持类型保留的二进制格式;若必须用CSV,则务必在读取后统一执行ast.literal_eval类型还原,并做好空值与异常处理。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











