Преобразование файла CSV в файл JSON

#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))