#python #json #csv
Вопрос:
Я пытаюсь преобразовать CSV-файл, разделенный разделителями, в файл JSON, и SetrecordID будет списком, а пары-списком словарей.
Входной файл CSV
SetrecordID|SetMatchScore|Pairs 100,101,102|90|"100-101,40","100-102,80","101-102,90" 103,104,105|80|"103-104,60","103-105,90","104-105,90" 106,107,108|65|"106-107,55","106-108,60","107-108,80" 109,110,111|95|"109-110,85","109-111,100","110-111,100"
Ожидаемый результат в формате JSON
[ { Date: system date SetrecordID:[100,101,102] SetMatchScore:90 Pairs:[ {Pair1:100-101,matchscore:40}, {Pair2:100-102,matchscore:80}, {Pair3:101-102,matchscore:90} ] }, { Date: system date SetrecordID:[103,104,105] SetMatchScore:90 Pairs:[ {Pair1:103-104,matchscore:60}, {Pair2:103-105,matchscore:90}, {Pair3:104-105,matchscore:90} ] } ]
Получение вывода в формате JSON
{ "SetrecordID":[ "109", "110", "111" ], "SetMatchScore":95, "Pairs":"109-110,85,"109-111,100","110-111,100"" }
Код Пробовал
df = pd.read_csv('filename.csv',sep="|") dict_val = {} for index, row in df.iterrows(): row["SetrecordID"] = row["SetrecordID"].split(",") dict_val.update(row)
печать(dict_val)
Ответ №1:
Просто Панды вам здесь не помогут. (К счастью, вам также не нужны Панды здесь.)
import csv, io, ast, json # Using a `StringIO` here instead of reading from a file # (but since `StringIO`s are file-like, you can substitute # an `open()` call here.) data = io.StringIO( """ SetrecordID|SetMatchScore|Pairs 100,101,102|90|"100-101,40","100-102,80","101-102,90" 103,104,105|80|"103-104,60","103-105,90","104-105,90" 106,107,108|65|"106-107,55","106-108,60","107-108,80" 109,110,111|95|"109-110,85","109-111,100","110-111,100" """.strip() ) rows = [] for row in csv.DictReader(data, delimiter="|", quoting=csv.QUOTE_NONE): pairs = [pair.split(",", 1) for pair in ast.literal_eval(row["Pairs"])] row["Pairs"] = [ {f"Pair{x}": key, "matchscore": int(val)} for x, (key, val) in enumerate(pairs, 1) ] row["SetrecordID"] = row["SetrecordID"].split(",") rows.append(row) with open("data.json", "w") as outf: json.dump(rows, outf, indent=2)
будет принимать эти данные в диктанты, с которыми вы можете работать (или просто выводить в файл JSON):
{'SetrecordID': ['100', '101', '102'], 'SetMatchScore': '90', 'Pairs': [{'Pair1': '100-101', 'matchscore': 40}, {'Pair2': '100-102', 'matchscore': 80}, {'Pair3': '101-102', 'matchscore': 90}]} {'SetrecordID': ['103', '104', '105'], 'SetMatchScore': '80', 'Pairs': [{'Pair1': '103-104', 'matchscore': 60}, {'Pair2': '103-105', 'matchscore': 90}, {'Pair3': '104-105', 'matchscore': 90}]} {'SetrecordID': ['106', '107', '108'], 'SetMatchScore': '65', 'Pairs': [{'Pair1': '106-107', 'matchscore': 55}, {'Pair2': '106-108', 'matchscore': 60}, {'Pair3': '107-108', 'matchscore': 80}]} {'SetrecordID': ['109', '110', '111'], 'SetMatchScore': '95', 'Pairs': [{'Pair1': '109-110', 'matchscore': 85}, {'Pair2': '109-111', 'matchscore': 100}, {'Pair3': '110-111', 'matchscore': 100}]}
Комментарии:
1. Это CSV-файл, и нам нужно читать его таким образом, а не хранить данные в строке.
2. Да
StringIO
, вы создаете файлоподобные объекты из строк. Вместоdata = io.StringIO(...)
этого ты можешьdata = open(...)
.3. пары = [pair.split(«,», 1) для пары в ast.literal_eval(строка[«Пары»])] Ошибка типа: индексы списка должны быть целыми числами или срезами, а не str
4. Вы уверены, что используете
DictReader()
? Это звучит так, как будто у вас есть строка списка, а не строка диктанта. Все, что я могу вам сказать, это то, что код, который я вставил выше, работает для предоставленных вами данных.5. Я обновил свой код, о котором идет речь. не могли бы вы, пожалуйста, проверить и сообщить мне о части пар .