вывод json со строками без сопоставления ключей

#python #json

#python #json

Вопрос:

У меня есть этот пример json, в котором я не уверен, какой наилучший способ сопоставить «url» и «failedCount» из раздела columns с каждой строкой в разделе rows, а затем вывести все в csv, чтобы это выглядело следующим образом

 url,failedCount
https://stefanolsen.com/favicon.ico, 663
https://stefanolsen.com/apple-touch-icon.png, 282
https://stefanolsen.com/apple-touch-icon-precomposed.png, 282
  

пример json:

 {
    "tables":[{
        "name":"Primary",
        "columns":[
        {
            "name":"url",
            "type":"string"
        },
        {
            "name":"failedCount",
            "type":"long"
        }],
        "rows":[
            ["https://stefanolsen.com/favicon.ico", 663],
            ["https://stefanolsen.com/apple-touch-icon.png", 282],
            ["https://stefanolsen.com/apple-touch-icon-precomposed.png", 282]

        ]
    }]
}
  

Пытался использовать код из https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas .Series.to_json.html но безуспешно

Ответ №1:

После просмотра содержимого примера ввода JSON, я думаю, лучшим подходом было бы написать что-то «управляемое данными» в том смысле, что имена столбцов не были жестко закодированы в нем. Это означало бы, что его не нужно было бы изменять, если бы у них были разные имена и / или их было разное количество.

 import csv
import json

json_sample = '''
{
    "tables":[{
        "name":"Primary",
        "columns":[
        {
            "name":"url",
            "type":"string"
        },
        {
            "name":"failedCount",
            "type":"long"
        }],
        "rows":[
            ["https://stefanolsen.com/favicon.ico", 663],
            ["https://stefanolsen.com/apple-touch-icon.png", 282],
            ["https://stefanolsen.com/apple-touch-icon-precomposed.png", 282]

        ]
    }]
}'''

filename = 'converted_json.csv'
json_obj = json.loads(json_sample)  # Deserialize.

table = json_obj['tables'][0]  # First table.
fields = [col['name'] for col in table['columns']]  # Extract table field names.

with open(filename, 'w', newline='') as outp:  # Create csv file from table.
    writer = csv.writer(outp)
    writer.writerow(fields)
    writer.writerows(table['rows'])

print('done')

  

Комментарии:

1. Спасибо за подход без жесткого кодирования имен столбцов

Ответ №2:

Все, что вам нужно сделать, это извлечь 'rows' ключ из данных JSON, он уже находится в нужном вам формате (который представляет собой список / кортеж списков / tuples).

 import csv

data = {
    "tables":[{
        ...,
        "rows":[
            ["https://stefanolsen.com/favicon.ico", 663],
            ["https://stefanolsen.com/apple-touch-icon.png", 282],
            ["https://stefanolsen.com/apple-touch-icon-precomposed.png", 282]
        ]
    }]
}

rows = data['tables'][0]['rows']

with open('test.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['url', 'failedCount'])
    writer.writerows(rows)
  

Затем test.csv содержит

 url,failedCount
https://stefanolsen.com/favicon.ico,663
https://stefanolsen.com/apple-touch-icon.png,282
https://stefanolsen.com/apple-touch-icon-precomposed.png,282
  

Не добавляйте пробел между запятой и числом, поскольку это затруднит синтаксический анализ csv-файла.

Ответ №3:

Смогли бы вы сделать что-то подобное?

 import csv

with open('output.csv', 'w ', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['url', 'failedCount'])
    for table in data['tables']:
        for row in table['rows']:
            writer.writerow([row[0], row[1]])