
CSV 格式不原生支持嵌套数据结构,当 Pandas 将含 list 类型(如 [1.5, -2, 3])的列写入 CSV 后,会自动转为字符串表示;读取时需手动解析还原为 Python 列表,否则 row[0] 将返回字符串首字符而非列表首元素。
csv 格式不原生支持嵌套数据结构,当 pandas 将含 list 类型(如 `[1.5, -2, 3]`)的列写入 csv 后,会自动转为字符串表示;读取时需手动解析还原为 python 列表,否则 `row[0]` 将返回字符串首字符而非列表首元素。
在处理如 Name, Age, Seq_1, Seq_2 这类混合类型数据时,若 Seq_1 和 Seq_2 是长度可变的数值列表(整数或浮点数),直接使用 df.to_csv() + pd.read_csv() 会导致列表被序列化为字符串(例如 [1.5, -2, 3] → "['1.5', '-2', '3']" 或 "[1.5, -2, 3]"),从而破坏原始数据结构。
这是因为 CSV 是纯文本格式,Pandas 在写入时调用 str() 将 list 转为字符串;读取时则作为普通字符串加载,不再具备可索引的 list 行为。
✅ 正确做法分两步:
1. 写入时无需额外操作(默认即可):
df.to_csv("../data/df.csv", index=False)
2. 读取后对目标列执行安全解析:
使用 ast.literal_eval —— 它能安全地将字符串形式的 Python 字面量(如 "[1, 2.5, -3]")还原为对应对象,且不执行任意代码,比 eval() 更安全:
import pandas as pd
import ast
df = pd.read_csv("../data/df.csv", low_memory=False)
# 将 Seq_1 和 Seq_2 列从字符串还原为 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 (原值,非字符串 '-')</class>
⚠️ 注意事项:
- 确保 CSV 中列表列的字符串格式合法(如
[1, 2.5, -3],不含多余空格或不可见字符);若存在缺失值(NaN),需先处理:df["Seq_1"] = df["Seq_1"].apply(lambda x: ast.literal_eval(x) if pd.notna(x) else [])
- 不推荐使用
json.loads()(需双引号、不兼容单引号)或eval()(存在代码注入风险)。 - 若数据规模极大,可考虑改用更合适的存储格式(如 Parquet、Feather 或 Pickle),它们原生支持复杂类型,避免序列化开销。
总结:CSV 仅适合扁平结构;保存 list 列时,务必在读取后通过 ast.literal_eval 显式还原,这是兼顾安全性与兼容性的标准实践。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











