невозможно преобразовать JSON в dataframe - PullRequest
0 голосов
/ 20 октября 2019

Я пытаюсь преобразовать огромный JSON-файл во фрейм данных, чтобы предварительно обработать его для анализа настроений. Но не удается его преобразовать.

Проблема в pd.read_json

import json
import pandas as pd

with open("/content/drive/My Drive/timeline_1.jsonl") as f:
    data = f.readlines()
    data_json_str = "[" + ','.join(data) + "]"
    data_df = pd.read_json(data_json_str)

ValueError: не соответствует '' "'при декодировании' string '

Ответы [ 2 ]

0 голосов
/ 11 ноября 2019

Использование pandas.io.json.json_normalize :

Данные:

  • Данные даны как list из dicts в файлес именем test.json
[{
        "id": "99014576299056245",
        "created_at": "2017-11-16T14:28:53.919Z",
        "sensitive": false,
        "spoiler_text": "",
        "language": "en",
        "uri": "mastodon.gamedev.place/users/jaggy/statuses/99014576299056245",
        "instance": "mastodon.gamedev.place",
        "content": "<p>Coding a cheeky skill before bed. Not as much as I&apos;d like but had drinks with co-workers after work so shrug ^_^</p>",
        "account_id": "434",
        "tag_list": [],
        "media_attachments": [],
        "emojis": [],
        "mentions": []
    }, {
        "id": "99014544879467317",
        "created_at": "2017-11-16T14:20:54.462Z",
        "sensitive": false,
        "spoiler_text": "",
        "language": "en",
        "uri": "mastodon.gamedev.place/users/jaggy/statuses/99014544879467317",
        "instance": "mastodon.gamedev.place",
        "content": "<p>Coding a cheeky skill before bed. Not as much as I&apos;d like but had drinks with co-workers after work so shrug ^_^</p>",
        "account_id": "434",
        "tag_list": [],
        "media_attachments": [],
        "emojis": [],
        "mentions": []
    }
]

Код для чтения данных:

import pandas as pd
import json
from pathlib import Path
from pandas.io.json import json_normalize

# path to file
p = Path(r'c:\some_directory_with_data\test.json')

# read the file in and load using the json module
with p.open('r', encoding='utf-8') as f:
    data = json.loads(f.read())

# create a dataframe
df = json_normalize(data)

# dataframe view
                id                created_at  sensitive spoiler_text language                                                            uri                instance                                                                                                                       content account_id tag_list media_attachments emojis mentions
 99014576299056245  2017-11-16T14:28:53.919Z      False                    en  mastodon.gamedev.place/users/jaggy/statuses/99014576299056245  mastodon.gamedev.place  <p>Coding a cheeky skill before bed. Not as much as I&apos;d like but had drinks with co-workers after work so shrug ^_^</p>        434       []                []     []       []
 99014544879467317  2017-11-16T14:20:54.462Z      False                    en  mastodon.gamedev.place/users/jaggy/statuses/99014544879467317  mastodon.gamedev.place  <p>Coding a cheeky skill before bed. Not as much as I&apos;d like but had drinks with co-workers after work so shrug ^_^</p>        434       []                []     []       []

Вариант 2:

Данные

  • Данные находятся в файле, в виде строк диктов
    • Нет в списке
    • Разделены новой строкой
  • Это недействительный файл JSON
{"id": "99014576299056245", "created_at": "2017-11-16T14:28:53.919Z", "sensitive": false, "spoiler_text": "", "language": "en", "uri": "mastodon.gamedev.place/users/jaggy/statuses/99014576299056245", "instance": "mastodon.gamedev.place", "content": "<p>Coding a cheeky skill before bed. Not as much as I&apos;d like but had drinks with co-workers after work so shrug ^_^</p>", "account_id": "434", "tag_list": [], "media_attachments": [], "emojis": [], "mentions": []}
{"id": "99014544879467317", "created_at": "2017-11-16T14:20:54.462Z", "sensitive": false, "spoiler_text": "", "language": "en", "uri": "mastodon.gamedev.place/users/jaggy/statuses/99014544879467317", "instance": "mastodon.gamedev.place", "content": "<p>Coding a cheeky skill before bed. Not as much as I&apos;d like but had drinks with co-workers after work so shrug ^_^</p>", "account_id": "434", "tag_list": [], "media_attachments": [], "emojis": [], "mentions": []}

Код для чтения этих данных

  • Чтение файла со следующим кодом
    • data будет спискомиз str, где каждая строка файла является str в списке
    • Используйте ast.literal_eval, чтобы преобразовать str обратно в диктовку
    • literal_eval вонне работает, если в str есть недопустимые значения (например, false вместо False, true вместо True).
    • Это приведет к ValueError: malformed node or string: <_ast.Name object at 0x000002B7240B7888>, что не является особенно полезной ошибкой
  • Я добавил блок try-except для печати любой строки, которая вызывает проблему, добавьтедо values_to_fix dict, пока вы не получите их все.
import pandas as pd
import json
from pathlib import Path
from pandas.io.json import json_normalize
from ast import literal_eval

# path to file
p = Path(r'c:\some_directory_with_data\test.json')

list_of_dicts = list()
with p.open('r', encoding='utf-8') as f:
    data = f.readlines()
    for x in data:
        values_to_fix = {'false': 'False',
                         'true': 'True',
                         'none': 'None'}
        for k, v in values_to_fix.items():
            x = x.replace(k, v)
        try:
            x = literal_eval(x)
            list_of_dicts.append(x)
        except ValueError as e:
            print(e)
            print(x)

df = json_normalize(list_of_dicts)

# this output is the same as that shown above
0 голосов
/ 20 октября 2019

Ваши данные, вероятно, повреждены, по крайней мере, в одном месте (может быть, больше).

Один из способов найти такое место - запустить код, а не весь файл,но на куски этого.

Например, запустите ваш код на:

  • первой половине вашего файла,
  • второй половине.

Если какая-либо часть работает нормально, то она не содержит ошибок.

Следующим шагом является повторение вышеописанной процедуры для каждого «сбойного» чанка.

ДругаяМетод : внимательно посмотрите на свой StackTrace, возможно, где-то есть номер строки в исходном файле *1022* (не путайте его с номером строки Python code ).

Пока вы собираете весь текст в виде одной строки , поэтому даже если StackTrace содержит такое число, скорее всего, это просто 1 .

Чтобы облегчить расследование, измените код таким образом, чтобы каждая строка исходного текста была в отдельной строке в объединенном тексте. Что-то вроде:

data_json_str = "[" + ',\n'.join(data) + "]"

Затем снова выполните свой код и прочитайте показанное число (где произошла ошибка), теперь равное номеру строки исходного текста.

Затем посмотрите на эту строку,исправьте его, и ваш код должен работать без ошибок.

Редактировать после вашего комментария исходные данные

В ваших данных я заметил, что:

  • содержит два объекта JSON (строки),
  • , но без без запятой между ними.

Я сделал следующие дополнения и изменения:

  • добавлено [ и ] в начале / конце,
  • добавлено запятая после первого {...} .

, чтобы входная строка была:

data_json_str = '''[
{"id": "99014576299056245", "created_at": "2017-11-16T14:28:53.919Z",
 "sensitive": false, "spoiler_text": "", "language": "en",
 "uri": "mastodon.gamedev.place/users/jaggy/statuses/99014576299056245",
 "instance": "mastodon.gamedev.place",
 "content": "<p>Coding a cheeky skill before bed. Not as much as I&apos;d like but had drinks with co-workers after work so shrug ^_^</p>",
 "account_id": "434", "tag_list": [], "media_attachments": [], "emojis": [], "mentions": []},
{"id": "99014544879467317", "created_at": "2017-11-16T14:20:54.462Z", "sensitive": false}
]'''

Затем выполнили инструкцию для чтения этой строки:

data_df = pd.read_json(data_json_str)

и получили DataFrame с2 строки (без ошибок). Первоначально я подозревал &apos; как возможный источник ошибки, но read_json справился и с этим делом.

Но когда я удалил запятую после первой {... } , я получил ошибку:

ValueError: Unexpected character found when decoding array value (2)

(другая ошибка, кроме вашей).

Я использую Python 3.7.0 и Pandas 0,25. Если у вас есть более старая версия Python или Pandas , может быть, вам стоит обновить их?

Настоящая проблема, вероятно, связана с некоторым "слабым местом" в JSONсинтаксический анализатор (я не уверен, является ли он частью Python или Pandas ).

Перед обновлением выполните еще один тест: отбросьте упомянутый &apos;из входной строки и попробуйте read_json снова.

Если вы получите на этот раз правильный результат, это подтвердит мое подозрение, что анализатор JSON в вашей установке имеет недостатки и будет важной поддержкоймоего совета по обновлению вашего программного обеспечения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...