【问题标题】:How can I export to CSV when JSON some records contain different keys当 JSON 某些记录包含不同的键时,如何导出到 CSV
【发布时间】:2019-09-16 05:52:28
【问题描述】:

我正在使用 API 来获取 JSON 结果,然后转换为 CSV。但是,我在结果中看到一些记录缺少键。结果是 CSV 的值转移到了错误的列

我已经运行了我的脚本并在 Postman 中运行了 API,并且 JSON 输出是相同的。我使用https://json-csv.com/ 将 JSON 转换为 CSV,并将其与我的输出进行比较。 https://json-csv.com/ 输出显示数据在正确的列中,让我相信后台有一些代码检测到丢失的键/值,并用空值填充它。

import json
import requests
import csv

def get_data():
    group_id = 9039
    api_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
    api_url = 'https://api.samsara.com/v1'
    endpoint_url = api_url + '/fleet/drivers'

    my_params = {"access_token": api_token}
    my_data = {"groupId": group_id}
    resp = requests.post(url = endpoint_url, params = my_params, json = my_data)
    array = resp.json()
    text = json.dumps(array)

    return text


def write_file(filename, text):
    dataset = json.loads(text)
    drivers = dataset['drivers']

    csvFile = open(filename,'w')
    csvwriter = csv.writer(csvFile)

    # write header
    if len(drivers) > 0:
        keys = drivers[0].keys()
        csvwriter.writerow(keys)

    # write data
    for line in drivers:
       csvwriter.writerow(line.values())

    csvFile.close()

text = get_data()
write_file('drivers.csv', text)

从 JSON 输出,这是部分结果。

{
    "drivers": [
        {
            "id": 158830,
            "groupId": 9039,
            "vehicleId": 212014918234731,
            "currentVehicleId": 212014918431705,
            "username": "rdoherty",
        },
        {
            "id": 134808,
            "groupId": 9039,
            "vehicleId": null,
            "username": "sbermingham",
        }

    ]
}

请注意,第二条记录没有“currentVehicleId”键:值。结果是,当我转换为 CSV 时,如果有缺失值,则所有其他值都将移动到它应该在的左侧的列中。

id  groupId vehicleId   currentVehicleId    username
158830  9039    2.12015E+14 2.12015E+14 rdoherty
134808  9039    null    sbermingham 

我希望 CSV 转换确保所有缺失值都替换为 null。

【问题讨论】:

    标签: python-3.x export-to-csv


    【解决方案1】:

    我建议修改字典并为缺少的任何键插入 drivers[key] = Nonedrivers[key] = ''

    第 1 步:获取所有可能的密钥

    如果您已经知道所有可能的密钥,这很容易。只需将所有键存储在一个列表中。
    如果没有,您将不得不遍历每个驱动程序并找到所有唯一键。

    # write header
    driver_keys = []
    for d in drivers:
        for key in d.keys():
            if key not in driver_keys:
                driver_keys.append(key)
    csvwriter.writerow(driver_keys)
    

    第 2 步:随时将空值添加到每一行。由于我们每次都迭代同一个列表(而不是修改它),我们可以保证相同的顺序,所以值应该与列标题匹配。

    # write data
    for line in drivers:
        for key in driver_keys:
            if key not in line.keys():
                line[key] = None  # or line[key] = '' if you like
        csvwriter.writerow(line.values())
    
    csvFile.close()
    

    【讨论】:

    • 你好,凯利。我使用您的建议进行了更新,并在 driver_keys[] 中添加了键列表。但是,当值被转移到错误的列时,我遇到了同样的问题。我确定我犯了一些非常基本的错误。还有其他推荐吗?
    • 嗨,加里。添加密钥列表后,您是否确保也完成了第 2 步?第 2 步至关重要,因为它会在您没有特定键:值对的列中添加一个“虚拟值”。如果我们逐行编写 .csv,我们必须添加这些空单元格,以便列正确排列。
    • 你好,凯利。是的,我做到了。在写入标题部分,我将所有键添加到 driver_keys 列表中 (driver_keys = ["id","groupId","vehicleId","currentVehicleId","username"]。然后我完全按照您提供的方式添加了写入数据代码.
    猜你喜欢
    • 2021-10-09
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-12
    • 2015-11-07
    • 2011-08-09
    相关资源
    最近更新 更多