Перекодировать JSON File Python

1

У меня сложная задача: загрузить json файл из формата и перекодировать в другом формате для загрузки в MongoDB. Мой json файл от Alpha Vantage (https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=1min&apikey=demo) и имеет следующий формат.

"Time Series (1min)": {
    "2018-07-13 16:00:00": {
        "1. open": "105.4550",
        "2. high": "105.5600",
        "3. low": "105.3900",
        "4. close": "105.4300",
        "5. volume": "2484606"
    },
    "2018-07-13 15:59:00": {
        "1. open": "105.5300",
        "2. high": "105.5300",
        "3. low": "105.4500",
        "4. close": "105.4600",
        "5. volume": "216617"
    }

Мне нужно повторно закодировать файл в соответствии со следующей схемой, используя День, час и минуту как ключи.

{
'2018-07-13': {
    '16': {
        '00': {'open': 105.4550,
              'high': 105.5600,
              'low': 105.3900,
              'close': 105.4300,
              'volume': 2484606,}
        }
    }
'2018-07-13': {
    '15': {
        '59': {'open': 105.53000,
              'high': 105.5300,
              'low': 105.4500,
              'close': 105.4600,
              'volume': 6484606,}
        }
    }
}

Я провел много исследований, но я не понял, как построить словарь с несколькими ключами, используя цикл, в то же время я прочитал json файл, который я бы хотел включить в Dict.

Теги:

1 ответ

1
Лучший ответ

Я согласен, что это может быть немного запутанным, если вы не привыкли работать с вложенными структурами данных, но это не так сложно, если вы будете осторожны. Хитрость заключается в создании внутренних словарей, если они еще не существуют. Мы можем сделать это с dict.setdefault метода dict.setdefault.

Нам также необходимо преобразовать внутренние данные из строк в числа. Но мы хотим, чтобы числа были целыми числами, если они не содержат десятичной точки, в противном случае мы хотим поплавки. Обычный способ сделать это показан в моей функции str_to_num. Сначала мы пытаемся преобразовать в целое число, и если это не удается, мы конвертируем в float. И если это не удается из-за плохих данных, программа повысит исключение ValueError и прекратит работу. Вы можете обращаться с этим по-другому, например, игнорировать плохие данные.

Я предполагаю, что вы знаете, как извлечь нужные данные с внешнего уровня, используя ключ "Time Series (1min)". В приведенном ниже коде используется стандартный модуль json для преобразования данных в новый формат обратно в JSON, чтобы мы могли его распечатать.

import json

alpha_data = {
    "2018-07-13 16:00:00": {
        "1. open": "105.4550",
        "2. high": "105.5600",
        "3. low": "105.3900",
        "4. close": "105.4300",
        "5. volume": "2484606"
    },
    "2018-07-13 15:59:00": {
        "1. open": "105.5300",
        "2. high": "105.5300",
        "3. low": "105.4500",
        "4. close": "105.4600",
        "5. volume": "216617"
    }
}

def str_to_num(s):
    try:
        n = int(s)
    except ValueError:
        n = float(s)
    return n

# Where we'll store the output
out_data = {}

for timestamp, data in alpha_data.items():
    datestr, timestr = timestamp.split()
    hr, mn, _ = timestr.split(':')
    # Fetch inner dicts, creating them if they don't exist yet
    d = out_data.setdefault(datestr, {})
    d = d.setdefault(hr, {})
    d[mn] = {k.split()[1]: str_to_num(v) for k, v in data.items()}

print(json.dumps(out_data, indent=4))  

выход

{
    "2018-07-13": {
        "16": {
            "00": {
                "open": 105.455,
                "high": 105.56,
                "low": 105.39,
                "close": 105.43,
                "volume": 2484606
            }
        },
        "15": {
            "59": {
                "open": 105.53,
                "high": 105.53,
                "low": 105.45,
                "close": 105.46,
                "volume": 216617
            }
        }
    }
}

Вы заметите, что мой вывод не совсем то же самое, что и ваш желаемый результат. Это потому, что ключи в словарях Python уникальны: у вас не может быть двух элементов в одном и том же dict с ключом "2018-07-13". Таким образом, мой код создает dict в out_data с ключом "2018-07-13" и внутри этого dict он при необходимости создает dict для каждого часа.

  • 0
    Удивительно, у меня целая неделя болит эта проблема, и вы решили в несколько строк, спасибо за объяснение, так как вы сказали, что мне не хватает некоторых знаний о структуре вложенных данных, и мой вывод был неверным, было два равных ключа в диктат, ваш вывод именно то, что мне нужно. Еще один последний вопрос, возможно ли создать одну переменную в день? Я хотел бы добавить один документ в день на MongoDB.
  • 0
    @FernandoSilva Извините, я не знаю MongoDB, поэтому я не могу дать вам какой-либо конкретный совет по этому поводу. Мой код обработает любое количество данных, которое соответствует формату в вашем вопросе. Он будет создавать отдельный dict для каждого дня, который он видит во входных данных.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню