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

Python保存含整数/字符串/列表的pandas DataFrame为txt并正确读取

问题根因

原有代码报错的核心原因是字段分隔符选择与存储方法不匹配:

  • OpenCV检测得到的轮廓是形状为(N,1,2)、dtype为int32的numpy数组,直接用to_string()导出时,轮廓内部的坐标值之间本身包含大量空白字符
  • 读取时设置的\s{1,}空白分隔符会把轮廓内部的每个坐标都识别成单独的字段,最终触发「字段数不匹配」的解析错误
  • 另外to_string()本身是面向终端打印的人类可读格式,不是为结构化存储设计的,不适合用于需要后续反序列化读取的场景。
可行实现方案

方案全程使用txt格式存储,读取后所有字段类型与原始DataFrame完全一致,轮廓数据不需要额外转换即可直接传入cv2.drawContours使用。

导出代码

导出时选择制表符\t作为分隔符(轮廓内容中不会出现制表符,不会产生分隔冲突),同时将numpy格式的轮廓序列化为可反解析的字符串:

import pandas as pd
import numpy as np
import ast
import cv2

# 基础字段类型转换
df_to_save['Height'] = df_to_save['Height'].astype(int)
df_to_save['Width'] = df_to_save['Width'].astype(int)
df_to_save['Label'] = df_to_save['Label'].astype(str)
# 序列化轮廓列:保留完整结构和数值信息
df_to_save['Contour'] = df_to_save['Contour'].apply(lambda x: repr(x))

# 写入txt文件,注意首次写入用w模式,避免追加重复表头
with open("savedDF.txt", "w", encoding="utf-8") as f:
    f.write(df_to_save.to_csv(sep="\t", index=False))

导入代码

读取时使用和导出一致的制表符分隔符,读取完成后将轮廓字符串反序列化回OpenCV要求的int32格式numpy数组:

# 读取txt文件
df_loaded = pd.read_csv("savedDF.txt", sep="\t", encoding="utf-8")
# 反序列化轮廓列,还原为OpenCV原生支持的轮廓格式
df_loaded["Contour"] = df_loaded["Contour"].apply(
    lambda x: np.array(ast.literal_eval(x), dtype=np.int32)
)

效果验证

读取完成后可以直接调用OpenCV接口绘制轮廓,不需要做额外格式转换:

# 创建空白测试图
canvas = np.zeros((2000, 2000, 3), dtype=np.uint8)
# 直接使用读取到的轮廓绘制
for idx, row in df_loaded.iterrows():
    cv2.drawContours(canvas, [row["Contour"]], -1, (0, 255, 0), 2)
# 保存结果验证
cv2.imwrite("contour_render.jpg", canvas)
注意事项
  • 存储包含嵌套结构、长文本的DataFrame时,禁止使用空白符作为分隔符,必须选择字段内容中绝对不会出现的特殊字符作为分隔符,比如制表符\t、不可见控制符等
  • 反序列化轮廓时必须显式指定dtype=np.int32,这是OpenCV轮廓相关接口要求的固定数据类型,默认int64类型会触发OpenCV接口报错
  • 如果需要追加写入数据,先读取已有txt合并后再整体重写,不要直接用a模式追加,否则会重复写入表头导致后续解析出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:24:09