Завантаження та аналіз файлу JSON з кількома об'єктами JSON


101

Я намагаюся завантажити та розібрати файл JSON у Python . Але я застряг, намагаючись завантажити файл:

import json
json_data = open('file')
data = json.load(json_data)

Врожайність:

ValueError: Extra data: line 2 column 1 - line 225116 column 1 (char 232 - 160128774)

Я подивився 18.2. json- Кодер і декодер JSON в документації Python, але читати цю жахливу документацію досить привабливо.

Перші рядки (анонімізовані рандомізованими записами):

{"votes": {"funny": 2, "useful": 5, "cool": 1}, "user_id": "harveydennis", "name": "Jasmine Graham", "url": "http://example.org/user_details?userid=harveydennis", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 2, "cool": 4}, "user_id": "njohnson", "name": "Zachary Ballard", "url": "https://www.example.com/user_details?userid=njohnson", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 0, "cool": 4}, "user_id": "david06", "name": "Jonathan George", "url": "https://example.com/user_details?userid=david06", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 6, "useful": 5, "cool": 0}, "user_id": "santiagoerika", "name": "Amanda Taylor", "url": "https://www.example.com/user_details?userid=santiagoerika", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 8, "cool": 2}, "user_id": "rodriguezdennis", "name": "Jennifer Roach", "url": "http://www.example.com/user_details?userid=rodriguezdennis", "average_stars": 3.5, "review_count": 12, "type": "user"}

Відповіді:


222

У вас є текстовий файл формату JSON Lines . Потрібно розібрати свій файл за рядком:

import json

data = []
with open('file') as f:
    for line in f:
        data.append(json.loads(line))

Кожен рядок містить дійсний JSON, але в цілому це не є дійсним значенням JSON, оскільки немає списку верхнього рівня або визначення об'єкта.

Зауважте, що оскільки файл містить JSON на рядок, вас врятують головні болі, намагаючись проаналізувати все це за один раз або розібратися в потоковому аналізаторі JSON. Тепер ви можете вибрати обробляти кожен рядок окремо, перш ніж перейти до наступного, зберігаючи пам’ять у процесі. Напевно, ви не хочете додавати кожен результат до одного списку, а потім обробляти все, якщо ваш файл дійсно великий.

Якщо у вас є файл, що містить окремі об’єкти JSON з роздільниками між ними, використовуйте Як я можу використовувати модуль 'json' для читання в одному об’єкті JSON за один раз? для розбору окремих об'єктів за допомогою буферизованого методу.


2
+1 Можливо, варто відзначити, що якщо вам не потрібні всі об'єкти одразу, обробка їх по одному може бути більш ефективним підходом. Таким чином вам не потрібно буде зберігати цілі дані в пам’яті, а єдиний фрагмент.
Тадек

1
@Pi_: у вас буде словник, тому просто перейдіть до полів як ключі:data = json.loads(line); print data[u'votes']
Martijn Pieters

1
@Pi_: надрукуйте результат json.loads (), а потім скористайтеся налагоджувачем для перевірки.
Martijn Pieters

1
@Pi_: ні; не плутайте формат JSON з поданням диктону python. Зараз ви бачите словники python із рядками.
Martijn Pieters

1
@ user2441441: дивіться пов’язану відповідь з поста тут.
Martijn Pieters

11

для тих, хто стикається з цим питанням: jsonlinesбібліотека python (набагато молодша за це питання) елегантно обробляє файли з одним документом json у рядку. дивіться https://jsonlines.readthedocs.io/


4

Те є погано відформатований. У вас є один об'єкт JSON на рядок, але вони не містяться у більшій структурі даних (тобто масиві). Вам або потрібно буде переформатувати його так, щоб він починався [і закінчувався ]комою в кінці кожного рядка, або розбирати його за рядком як окремі словники.


20
Маючи файл розміром 50 Мб, ОП, мабуть, краще справлятися з даними рядком за рядком. :-)
Martijn Pieters

11
Чи неправильно відформатований файл, залежить від точки зору. Якщо вона мала бути у форматі "Рядки JSON", це дійсно. Дивіться: jsonlines.org
LS
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.