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
相关产品推荐
相关产品推荐

