#python #json #csv #key
#python #json #csv #Клавиша
Вопрос:
Я пытаюсь преобразовать свой файл CSV в формат файла JSON. Когда я это делаю, в файле JSON появляется дополнительная запись, которая содержит только имена полей.
Я пытался использовать pandas, dictionary, но, похоже, не могу получить результат. Приходит что-то или другое.
Я хочу удалить дополнительную запись только для имен файлов в начале JSON. Также, как я могу сделать connectionId в качестве ключа и тот же формат для другого вывода.
import csv, json
csvfile = open('/home/Desktop/PD/GEOSubscriberLocations_LTE_sample.csv', 'r')
jsonfile = open('/home/Desktop/PD/script5.json', 'w')
fieldnames = ("Confidence", "ConnectionId", "Imei", "Imsi", "IsData", "IsSignalling", "IsVoice", "Latitude", "Longitude",
"Mcc", "Mnc", "SegmentDuration", "SegmentStartTime", "ServingCellLabel", "Sv",
"TrackingAreaCode", "Uncertainity")
reader = csv.DictReader(csvfile , fieldnames)
code = ''
for row in reader:
for key in row:
row[key] = row[key].decode('utf-8', 'ignore').encode('utf-8')
json.dump(row, jsonfile, indent=4, sort_keys=False)
jsonfile.write('n')
Фактический результат:
{
"Confidence": "Confidence",
"IsData": "IsData",
"Latitude": "Latitude",
"ConnectionId": "ConnectionId",
"Mcc": "Mcc",
"Sv": "Sv",
"Longitude": "Longitude",
"Uncertainity": "Uncertainty",
"IsVoice": "IsVoice",
"IsSignalling": "IsSignalling",
"SegmentStartTime": "SegmentStartTime",
"Imei": "Imei",
"SegmentDuration": "SegmentDuration",
"Mnc": "Mnc",
"ServingCellLabel": "ServingCellLabel",
"Imsi": "Imsi",
"TrackingAreaCode": "TrackingAreaCode"
}
{
"Confidence": "1.994667E-07",
"IsData": "FALSE",
"Latitude": "1.694202",
"ConnectionId": "330708186825281",
"Mcc": "999",
"Sv": "01",
"Longitude": "0.434623",
"Uncertainity": "178",
"IsVoice": "FALSE",
"IsSignalling": "TRUE",
"SegmentStartTime": "16/02/2017 09:56:59.912",
"Imei": "99999006686069",
"SegmentDuration": "00:00:00.0350000",
"Mnc": "99",
"ServingCellLabel": "Cell18",
"Imsi": "999992223223602",
"TrackingAreaCode": "1234"
}
{
"Confidence": "1.504506E-12",
"IsData": "FALSE",
"Latitude": "1.633704",
"ConnectionId": "260339442647675",
"Mcc": "999",
"Sv": "02",
"Longitude": "0.668554",
"Uncertainity": "314",
"IsVoice": "FALSE",
"IsSignalling": "TRUE",
"SegmentStartTime": "16/02/2017 09:57:01.377",
"Imei": "99999207564306",
"SegmentDuration": "00:00:00.0280000",
"Mnc": "99",
"ServingCellLabel": "Cell19",
"Imsi": "999993793410366",
"TrackingAreaCode": "1235"
}
{
"Confidence": "0.3303348",
"IsData": "FALSE",
"Latitude": "1.847635",
"ConnectionId": "260339442647676",
"Mcc": "999",
"Sv": "14",
"Longitude": "1.356349",
"Uncertainity": "129",
"IsVoice": "FALSE",
"IsSignalling": "TRUE",
"SegmentStartTime": "16/02/2017 09:57:01.555",
"Imei": "99999605176135",
"SegmentDuration": "00:00:00.0290000",
"Mnc": "99",
"ServingCellLabel": "Cell13",
"Imsi": "999992216631694",
"TrackingAreaCode": "1236"
}
{
"Confidence": "0.01800376",
"IsData": "FALSE",
"Latitude": "1.914598",
"ConnectionId": "330708186825331",
"Mcc": "999",
"Sv": "74",
"Longitude": "1.222736",
"Uncertainity": "463",
"IsVoice": "FALSE",
"IsSignalling": "TRUE",
"SegmentStartTime": "16/02/2017 09:57:02.689",
"Imei": "99999007880884",
"SegmentDuration": "00:00:00.0260000",
"Mnc": "99",
"ServingCellLabel": "Cell7",
"Imsi": "999992226681236",
"TrackingAreaCode": "1237"
}
{
"Confidence": "0.2068138",
"IsData": "FALSE",
"Latitude": "1.850279",
"ConnectionId": "330708186825354",
"Mcc": "999",
"Sv": "13",
"Longitude": "1.349263",
"Uncertainity": "167",
"IsVoice": "FALSE",
"IsSignalling": "TRUE",
"SegmentStartTime": "16/02/2017 09:57:04.351",
"Imei": "99999002855874",
"SegmentDuration": "00:00:00.0300000",
"Mnc": "99",
"ServingCellLabel": "Cell15",
"Imsi": "999995430231562",
"TrackingAreaCode": "1238"
}
При использовании connectionId в качестве ключа я хочу, чтобы мой вывод выглядел так:
{
"ConnectionId": "189970698469977",
{
"Confidence": "0.01428183",
"Imei": "99999507405260",
"Imsi": "999992226504812",
"IsData": "FALSE",
"IsSignalling": "TRUE",
"IsVoice": "FALSE",
"Latitude": "1.848613",
"Longitude": "1.354355",
"Mcc": "999",
"Mnc": "99",
"SegmentDuration": "00:00:00.0860000",
"SegmentStartTime": "16/02/2017 09:57:00.053",
"ServingCellLabel": "Cell14",
"Sv": "06",
"TrackingAreaCode": "1256",
"Uncertainty": 662
}
Ответ №1:
Попробуйте заменить for
цикл следующим кодом:
arr = []
with open (csvFile) as f:
csvReader = csv.DictReader(f)
#print(csvReader)
for csvRow in csvReader:
arr.append(csvRow)
print(arr)
# write the data to a json file
with open(jsonFile, "w") as jsonFile:
jsonFile.write(json.dumps(arr, indent = 4))
Пожалуйста, также обратитесь к этой ссылке.
Комментарии:
1. Спасибо @dexter. Решение сработало. Но я хочу убрать квадратные скобки, которые есть в начале и в конце. Также как я могу сделать connectionId в качестве ключа
2. не могли бы вы приложить файл csv, чтобы я мог попробовать.
3. @KaranSaxena Если вы уберете квадратные скобки, это больше не будет допустимым JSON. Есть ли какая-то особая причина, по которой вы хотите избавиться от них?
4. connectionId не является уникальным. Для одного идентификатора подключения имеется от 4 до 6 записей
5. @JaredKhan Программа JAVA будет использовать этот JSON для вставки данных в базу данных. Так это создаст проблему, квадратную скобку?
Ответ №2:
Дополнительная запись только для имен полей
Если вы укажете имена полей явно, csv
будет предполагаться, что первая строка файла .csv — это данные. Если вы не укажете параметр fieldnames, он будет считать, что первая строка файла .csv является строкой заголовка с именами полей:
Параметр fieldnames представляет собой последовательность. Если значение fieldnames опущено, в качестве имен полей будут использоваться значения в первой строке файла f.
Похоже, что ваш файл .csv имеет строку заголовка, но вы также явно указали имена полей, поэтому csv
он считывается в строке заголовка как данные. Чтобы просто использовать имена полей в строке заголовка, измените вызов DictReader на:
csv.DictReader(csvfile) # notice no fieldnames parameter
Использование определенного поля в качестве ключа
Сначала подумайте, как лучше всего представить это в JSON и что вы пытаетесь получить от индексации по этому полю, приведенный вами пример не совсем корректный JSON.
{
"ConnectionId": "189970698469977",
{
"Confidence": "0.01428183",
"Imei": "99999507405260",
...
}
Это недопустимо, потому что:
- Мы открываем
{
, указывая, что это «объект» - Объекты имеют ключи и значения, связанные с этими ключами, и ничего больше
- Мы предоставляем ключ ‘connectionId’ и значение для него. Это нормально
- Затем мы предоставляем другой объект, но без ключа, это недопустимо.
Предполагая, что вы хотите иметь возможность быстрого поиска объектов на основе идентификатора соединения, как насчет создания объекта в формате JSON, который выглядит следующим образом:
{
"189970698469977": {
"Confidence": "0.01428183",
"Imei": "99999507405260",
...
},
"260339442647676": {
"Confidence": ...
},
...
}
Это дает нам такое удовлетворяющее свойство, что JSON будет действительным только в том случае, если ключи уникальны.
Для этого нам нужно создать словарь на Python, который мы представим в дампе JSON:
Мы можем создавать словари Python из последовательности (key, value)
кортежей. Пример из документации:
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'guido': 4127, 'jack': 4098}
Мы будем использовать этот конструктор для создания нашего индексированного словаря:
dictionaryEntries = [(row['ConnectionId'], row) for row in csvReader]
dictionaryToDump = dict(dictionaryEntries)
Собираем это вместе
Теперь ваш код может выглядеть следующим образом:
import csv
import json
with open('mycsv.csv') as csvFile:
csvReader = csv.DictReader(csvFile)
dictionaryEntries = [(row['ConnectionId'], row) for row in csvReader]
dictionaryToDump = dict(dictionaryEntries)
with open('myjson.json', 'w') as jsonFile:
jsonFile.write(json.dumps(dictionaryToDump))