读写CSV字典数组,包含任意长度的列表

时间:2018-11-06 15:02:02

标签: python csv numpy

我目前正在将下面的字典数组写入一个csv文件:

tmp_res = [{"val1": 1.0, "val2": 2, "ar_1": [[65.41156005859375, 53.709598541259766], [251.97698974609375, 153.14926147460938]] },....]

ar1表示任意长度*ndarray*的{​​{1}},而[-1,2]在Dicts中不是恒定的。

读取后,我得到了-1val1的单个值,但是该数组不容易读取。

val2

我知道我可以遍历该字符串,并用一些字符分隔它。 但是,似乎应该对此有一个更好,更优雅的解决方案来解决此问题。

将此类数据保存到文件并还原的最佳方法是什么?

编辑: 为了澄清我的保存和读取文件。我通过"[[65.41156005859375, 53.709598541259766], [251.97698974609375, 153.14926147460938]]" 通过以下方式保存文件:


csv.DictWriter

# Exemplary Data:
results = [{'mean_iou': 0.3319194248978337, 'num_boxes': 1, 'centroids': [[101.21826171875, 72.79462432861328]]}, {'mean_iou': 0.4617333142965009, 'num_boxes': 2, 'centroids': [[65.41156005859375, 53.709598541259766], [251.97698974609375, 153.14926147460938]]}, {'mean_iou': 0.537150158582514, 'num_boxes': 3, 'centroids': [[50.82071304321289, 42.616580963134766], [304.91583251953125, 176.09994506835938], [140.43699645996094, 104.00206756591797]]}]

# The given results data is basically tmp_res after the for loop.
tmp_res = []
for i in range(0, len(results):
    res_dict = {}
    res_dict["centroids"] = results[i]["centroids"]
    res_dict["mean_iou"] = results[i]["mean_iou"]
    res_dict["num_boxes"] = results[i]["num_boxes"]
    tmp_res.append(res_dict)

# Writing to File
keys = tmp_res[0].keys()
with open('anchor.csv','w+') as output_file:
    dict_writer = csv.DictWriter(output_file, keys)
    dict_writer.writeheader()
    dict_writer.writerows(tmp_res)

文件摘录如下:

# Reading from File

  num_centroids = []
  mean_ious = []
  centroids = []
  reader = csv.DictReader(csvfile,
                          fieldnames=["mean_iou",
                                      "num_boxes",
                                      "centroids"])
        # Skipping line of the header
        next(reader, None)
        for row in reader:
            centroids.append(row["centroids"])
            num_centroids.append(row["num_boxes"])
            mean_ious.append(row["mean_iou"])

我怀疑csv.DictWriter不知道如何处理多个值的数组,因为它包含一个逗号,这会破坏逗号分隔值的格式。因此,它将“数据”包装成一个字符串,以避免strucutre中发生冲突。


在阅读Serges答案和您的评论时,我认为使用JSON结构而不是CSV可以更好地满足我的需求。它很容易支持我要寻找的结构。

但是我认为mean_iou,num_boxes,centroids 0.3319194248978337,1,"[[101.21826171875, 72.79462432861328]]" 0.4617333142965009,2,"[[65.41156005859375, 53.709598541259766], [251.97698974609375, 153.14926147460938]]" 0.537150158582514,3,"[[50.82071304321289, 42.616580963134766], [304.91583251953125, 176.09994506835938], [140.43699645996094, 104.00206756591797]]" 0.5602804262309611,4,"[[49.9361572265625, 41.09553146362305], [306.10711669921875, 177.09762573242188], [88.86656188964844, 167.8087921142578], [151.82627868652344, 81.80717468261719]]" 将能够处理其自身的“以字符串包装”数据的某种形式的包装。

也为您的延迟感到抱歉。


解决方案:来自Serge的解决方案已应用到代码中:

csv.dictWriter

1 个答案:

答案 0 :(得分:-1)

您的文件不是csv格式,它只是python字典。只需将文件读入字符串并使用<ItemsControl ItemsSource="{Binding Panes}"> <ItemsControl.ItemTemplate> <DataTemplate> <ContentPresenter Content="{Binding}" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 语句(危险但容易)或编写自定义解析器,例如,将字符串分解为数组,除去逗号和括号,应用np.fromstring然后重新整形。

好奇eval似乎是有效的json,因此 "[[65.41156005859375, 53.709598541259766], ..."应该导致一个ndarray。请注意,np.array( json.loads ( "[[65.41156005859375, 53.709598541259766], [251.97698974609375, 153.14926147460938]]" ))不是有效的json,因此tmp_res =将失败

PS。 CSV仅适用于表格数据,不适用于多维数据。如果必须的话,可以使用标准csv进行双重csv并拆分

json.load('myfile')

我想,一个更好的解决方案是将数据存储在有效的json中(不分配任何内容)。或者,您可以尝试使用指定的s = "[[76 ... " lines = s.split(']], [[') reader = csv.reader(lines, delimiter=', ') or use panda from_csv you can define ]], [[ as lineseparator in C mode. 存储二进制数据以提高可伸缩性。

其他可行的替代方法,请阅读

How can I serialize a numpy array while preserving matrix dimensions?

PS。 CSV旨在用于表格数据,而不是用于任意的多维数据,因此在这里只是选择不佳。不过,如果需要的话,您可以使用双csv阅读器,尽管它看起来很丑

numpy.save numpy.load

或者您可以修改熊猫csv阅读器,甚至它具有自定义行定界符。也许一些更强大的csv库会更好地工作。