Есть ли способ масштабировать эту программу для обработки нескольких строк размером JSON? - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь написать код, который принимает входные данные как несколько вложенных JSON объектов (каждый объект находится в новой строке) -

{JSONObject1}
{JSONObject2}
.
.
{JSONObjectn}

из текстового файла и в конечном итоге сглаживает и конвертирует их в файл CSV. Программа, на которую я ссылался - https://towardsdatascience.com/flattening-json-objects-in-python-f5343c794b10

, в настоящее время преобразует одну такую ​​строку вложенного объекта JSON из текстового файла и записывает ее в файл csv.

Как я могу масштабировать этот код для работы с «n» такими JSON объектами данных, все в отдельных строках текстового файла?

Вот мой текущий код -

import pandas as pd
import json

f = open('input.txt', )
data = json.load(f)


def flatten_json(y):
    out = {}

    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + '_')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + str(i) + '_')
                i += 1
        else:
            out[name[:-1]] = x

    flatten(y)
    return out


flat = flatten_json(data)
df = pd.json_normalize(flat)
export_csv = df.to_csv(r'output.csv')

Спасибо.

Ответы [ 3 ]

0 голосов
/ 20 июня 2020

Спасибо, Итан! С помощью вашего кода я создал обновленную версию кода, которая работает без сбоев! Я знаю, что вы упомянули многопоточность, и сейчас я исследую это в качестве следующего шага. В настоящее время приведенный ниже код занимает около 1 минуты для обработки 150 наборов данных, включая

  • чтение из файла
  • выполнение запроса на получение к API
  • сглаживание вложенный ответ JSON и
  • , а затем записать все сразу в файл CSV).

Есть какие-нибудь предложения относительно того, как мы можем обрабатывать тысячи строк данных, не тратя часы на выполнение?

Обновленный код -


import pandas as pd
import requests


def flatten_json(y):
    out = {}

    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + '_')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + str(i) + '_')
                i += 1
        else:
            out[name[:-1]] = x

    flatten(y)
    return out


data = []

with open('input.txt') as f_input:
    for id in f_input:
        url = "API_url"
        PARAMS = {'param1': id.strip()}
        resp = requests.get(url, headers={
            'headerkey': 'headervalue'}, params=PARAMS)
        flat = flatten_json(resp.json())
        df = pd.json_normalize(flat)
        data.append(df)

export_csv = pd.concat(data).to_csv(r'output.csv')

0 голосов
/ 21 июня 2020

Это быстрый пример того, как вы можете этого добиться. Обычно он создает 4 процесса, и каждый процесс будет захватывать 4 строки за раз, чтобы преобразовать его в json.

import json
import pandas as pd
from multiprocessing import Pool

def flatten_json(y):
    out = {}

    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + '_')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + str(i) + '_')
                i += 1
        else:
            out[name[:-1]] = x

    flatten(y)
    return out


def parse_line(line):
    data = json.loads(line)
    flat = flatten_json(data)
    return pd.json_normalize(flat)

if __name__ == "__main__":
    pool = Pool(4)
    with open('foo.txt', 'r') as f:
        dfs = pool.map(parse_line, f, 4)
        pool.close()
        pd.concat(dfs).to_csv('output.csv')
0 голосов
/ 19 июня 2020

я думаю l oop через файл это все, что вам нужно? Тогда просто выполните:

f = open('input.txt', 'r')
dfs = []
for line in f:
    data = json.loads(line)
    flat = flatten_json(data)
    df = pd.json_normalize(flat)
    dfs.append(df)
export_csv = pd.concat(dfs).to_csv('output.csv')

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

...