簡體   English   中英

讀/寫包含任意長度列表的CSV字典數組

[英]Read/write CSV Array of Dicts containing an list of arbitrary length

我目前正在將下面的字典數組寫入一個csv文件:

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

ar1表示任意長度[-1,2]*ndarray* ,- -1在Dicts中不是恆定的。

讀取后,我按預期得到了val1val2的單個值,但是該數組不容易讀取。

"[[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"])

該文件的摘錄如下所示:

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]]"

我懷疑csv.DictWriter不知道如何處理多個值的數組,因為它包含一個Comma ,這會破壞逗號分隔值的格式。 因此,它將數據包裝到字符串中,以避免結構沖突。


在閱讀Serges答案和您的評論時,我認為使用JSON結構而不是CSV可以滿足我的需求。 它很容易支持我正在尋找的結構。

但是我認為csv.dictWriter能夠處理某種形式的自身“ to-string-wrapped”數據的解包。

也為延遲感到抱歉。


解決方案:來自Serge的解決方案應用於代碼中:

#Added Json
import json
# 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(json.loads(row["centroids"]))
    num_centroids.append(row["num_boxes"])
    mean_ious.append(row["mean_iou"])

您的文件不是csv格式,只是python字典。 只需將文件讀入字符串並使用eval語句(危險但容易)或編寫自定義解析器,例如,將字符串分解為數組,除去逗號和括號,應用np.fromstring然后進行整形即可。

好奇地"[[65.41156005859375, 53.709598541259766], ..."看起來像是一個有效的json,所以np.array( json.loads ( "[[65.41156005859375, 53.709598541259766], [251.97698974609375, 153.14926147460938]]" ))應該導致ndarray結果。 注意tmp_res =無效的json,因此json.load('myfile')將失敗

PS。 CSV僅適用於表格數據,不適用於多維數據。 如果必須,您可以使用標准csv進行雙重csv並拆分

s = "[[76 ... "
lines = s.split(']], [[')

reader = csv.reader(lines, delimiter=', ')

or use panda from_csv you can define ]], [[ as lineseparator in C mode.

我猜,更好的解決方案是將數據存儲在有效的json中(不分配任何內容)。 或者,您可以嘗試使用指定的numpy.save numpy.load存儲二進制數據,以實現更大的可伸縮性。

有關其他可行的替代方法,請閱讀

如何在保留矩陣尺寸的同時序列化一個numpy數組?

PS。 CSV旨在用於表格數據,而不是用於任意的多維數據,因此在這里只是選擇不佳。 盡管如此,如果您必須的話,您可以使用雙csv閱讀器,盡管看起來很丑

text = "[[6... 
lines = text.split("]], [[")
reader2 = csv.reader(lines, delimiter=', ')
...

或者您也可以修改熊貓csv閱讀器,甚至可以使用自定義行定界符。 也許一些更強大的csv庫會更好地工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM