Python:将整数列表写入 .csv 文件并读回相同格式

Python: Writing list of integers to .csv file and reading back to same format

我有一个典型的复制和粘贴语法混淆,可能是因为我不太明白我在做什么!

我正在尝试保存从 mediapipe 库中收集的一系列 facemark_landmark 坐标。我遍历一部电影的帧,每一帧给我 468 个整数对,每个地标的屏幕坐标。

每一帧我都将坐标列表添加到名为 stored_data

的列表中
stored_data.append(landmark_coords)

电影结束后,我将数据写入文件:

with open("out.csv", "w") as f:
        wr = csv.writer(f)
        wr.writerows(stored_data)

这似乎工作正常,我的 csv 文件如下所示:(181, 95) , (170, 87) , ..... 每行468对,电影每一帧一行。

但我在尝试将 csv 文件转换回正确格式时遇到了麻烦。

我目前的努力是:

stored_data = []

with open("out.csv", "r") as f:
        rr = csv.reader(f)   
        for row in rr:
            frland=[]
            for l in row:
                coords = [map(float,l.split(',')) for i in l]
                frland.append(coords)
            stored_data.append(frland)

我收到错误:ValueError:设置带有序列的数组元素。请求的数组在 1 维后具有不均匀的形状。检测到的形状是(468,)+不均匀部分。

谁能帮帮我?

根据我的经验,CSV 用于在不同的人和进程之间共享数据。 CSV 本身没有本机类型,所有内容都被序列化为字符串,但是,是的,现在您在尝试读回某些值时遇到了问题解码

并且因为您必须解码,所以这是一个很好的指标,表明其他内容可能比 CSV 更好。如果您只需要在进程之间存储 mediapipe 结果,我重复 Ari 在评论中所说的,使用 pickle:它可以存储复杂类型,这样您就可以避免考虑编码和解码,并使其像“保存”一样简单,然后打开":

import pickle

orig_stored_data = [[(181, 95), (170, 87)], [(20, 40), (30, 50)]]

f_pickle = open("stored_data.pkl", "wb")
pickle.dump(orig_stored_data, f_pickle)

f_pickle = open("stored_data.pkl", "rb")
new_stored_data = pickle.load(f_pickle)

assert new_stored_data == orig_stored_data

如果您必须使用 CSV,则需要正确解释每一列中的元组。我认为这是不完整的:

coords = [map(float,l.split(',')) for i in l]

因为您在按逗号拆分之前没有删除括号。

更straight-forward的做法是使用ast模块中的literal_eval()函数:

import ast, csv, io, pprint

f_in = io.StringIO('"(181, 95)","(170, 87)"\n"(  20,   40)","(30,50)"')

stored_data = []

reader = csv.reader(f_in)
for row in reader:
    frland = []
    for col in row:
        coords = ast.literal_eval(col)
        frland.append(coords)
    stored_data.append(frland)

stored_data 看起来像:

[[(181, 95), (170, 87)],
 [(20, 40), (30, 50)]]