Странная JSON конвертация в CSV - PullRequest
1 голос
/ 09 мая 2020

У меня есть данные размером около 700 МБ в виде:

{"hash":"b2f405b1589efd8b013869d1d5e605367643db20844572ea7bf788f8575c38d6","block_timestamp":"2020-05-08 13:21:33 UTC","addresses":["3E17PiWGJqP8945KRZHuPdsFSU59othGEQ"]}
{"hash":"6609073b5979d768933f2ea7d4f1723d07c03a3e08f48adff21b9f1d79cee164","block_timestamp":"2020-05-08 13:39:39 UTC","addresses":["3CfewsC7Xjp2oJSBT2zUQkYSXfzo2nuGha"]}
{"hash":"5c7d95f903ea505d9ab82d1090944780c00e91d343ae66e94610bff1d614f90f","block_timestamp":"2020-04-05 23:19:30 UTC","addresses":["1ztVt2xwNwgzH3W9SJ2nMgPMuZpUg8m5w"]}
{"hash":"7eb120e9b50dbc25f13415b3c899efe2cfaf870a7f49995aa6e3b672a1992e56","block_timestamp":"2020-04-08 05:41:51 UTC","addresses":["1HckjUpRGcrrRAtFaaCAUaGjsPx9oYmLaZ"]}
{"hash":"be202b37aa218461827138ff32e3dfa74945808f3ecb574fb5287e99c8ae6a33","block_timestamp":"2020-04-04 09:53:28 UTC","addresses":["3Jk8HaC8Sjq6Ufig9NkWFoFcfzC5a3CNyL"]}

В настоящее время я сохранил эти данные в формате файла JSON. Я хочу преобразовать его в CSV. Выполнение этого с помощью общих методов python и BASH не дает правильного результата (обратите внимание, что между двумя строками нет запятой, это просто новая строка)

Я хочу, чтобы это было в CSV с заголовками: ha sh, block_timestamp и адресами. Как мне это сделать?

Ответы [ 5 ]

3 голосов
/ 09 мая 2020

Самый простой способ - сделать это одной строкой bash. Например, если ваш файл называется tt, просто запустите:

cat tt | sed -e "s/:/,/g" | awk -F"," '{print $2 "," $4 "," $6}'

В качестве альтернативы, если вы действительно хотите сделать это в Python, прочитайте файл построчно, используйте json.loads для проанализируйте каждую строку, а затем распечатайте строку в формате CSV (это то, что делает ranka47 в своем ответе). Уловка - это намного медленнее для больших файлов.

2 голосов
/ 09 мая 2020

Думаю, это то, что вы хотели. Предполагая, что есть только один адрес в каждом ключе addresses в JSON.

ПРИМЕЧАНИЕ: As Python будет загружать каждую строку за раз, поэтому он может обрабатывать большие данные если вы читаете построчно.

import json
fp = open("input.txt", "r")
ofp = open("output.txt", "w")

ofp.write("hash,block_timestamp,addresses\n")
for line in fp:
  json_obj = json.loads(line)
  # print(json_obj)
  ofp.write(json_obj["hash"] + "," + json_obj["block_timestamp"] + "," + json_obj["addresses"][0] + "\n")

fp.close()
ofp.close()

fp = open("output.txt")
for line in fp:
  print(line)

Вывод:

hash,block_timestamp,addresses
b2f405b1589efd8b013869d1d5e605367643db20844572ea7bf788f8575c38d6,2020-05-08 13:21:33 UTC,3E17PiWGJqP8945KRZHuPdsFSU59othGEQ
6609073b5979d768933f2ea7d4f1723d07c03a3e08f48adff21b9f1d79cee164,2020-05-08 13:39:39 UTC,3CfewsC7Xjp2oJSBT2zUQkYSXfzo2nuGha
5c7d95f903ea505d9ab82d1090944780c00e91d343ae66e94610bff1d614f90f,2020-04-05 23:19:30 UTC,1ztVt2xwNwgzH3W9SJ2nMgPMuZpUg8m5w
7eb120e9b50dbc25f13415b3c899efe2cfaf870a7f49995aa6e3b672a1992e56,2020-04-08 05:41:51 UTC,1HckjUpRGcrrRAtFaaCAUaGjsPx9oYmLaZ
be202b37aa218461827138ff32e3dfa74945808f3ecb574fb5287e99c8ae6a33,2020-04-04 09:53:28 UTC,3Jk8HaC8Sjq6Ufig9NkWFoFcfzC5a3CNyL
1 голос
/ 09 мая 2020

Если у вас pandas, вы можете сделать следующее:

import json
import pandas as pd


contents = [json.loads(line) for line in open("input.txt", 'r')]
df = pd.DataFrame(contents)
df.to_csv("output.csv", index=False)
1 голос
/ 09 мая 2020

Это можно сделать путем десериализации каждой строки и передачи полученного dict в csv.DictWriter .

import csv
import json

with open('data.json') as jf, open('data.csv', 'w', newline='') as f:
    # Handle the first row individually because we need to work out the
    # column headings
    line = next(jf)
    dict_ = json.loads(line)
    writer = csv.DictWriter(f, dict_.keys())
    writer.writerow(dict_)
    # Loop through the rest of the file
    for line in jf:
        dict_ = json.loads(line)
        writer.writerow(dict_)

Если вам не нужна строка заголовка, код можно упростить, используя csv.writer

with open('data.json') as jf, open('data.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    for line in jf:
        dict_ = json.loads(line)
        writer.writerow(dict_.values())
0 голосов
/ 09 мая 2020

На самом деле, моя идея, самый простой способ: - открыть файл с помощью мощного редактора, так как размер вашего файла большой. - заменить все ключи dict пустым текстом, например: заменить <"ha sh":> на пустой ... - заменить {,}, [,] также пустым текстом. - Левая часть хорошего формата CSV.

Ха-ха, код не нужен.

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