【问题标题】:Converting a nested JSON to CSV in Python在 Python 中将嵌套的 JSON 转换为 CSV
【发布时间】:2019-04-04 07:42:44
【问题描述】:

我想将嵌套的 json 转换为 csv 文件。
我正在从 Rest API 接收 json。
csv 中的字段应如下所示。
daterange_start、daterange_end、点击次数、展示次数、数据透视值。
我是 Python 和 JSON 的新手,所以很想得到一些帮助。
这是示例 json。

{
    "elements": [
        {
            "dateRange": {
                "start": {
                    "month": 3,
                    "year": 2019,
                    "day": 3
                },
                "end": {
                    "month": 3,
                    "year": 2019,
                    "day": 3
                }
            },
            "clicks": 11,
            "impressions": 2453,
            "pivotValues": [
                "urn:li:sponsoredCampaign:1234567"
            ]
        },
        {
            "dateRange": {
                "start": {
                    "month": 3,
                    "year": 2019,
                    "day": 7
                },
                "end": {
                    "month": 3,
                    "year": 2019,
                    "day": 7
                }
            },
            "clicks": 1,
            "impressions": 629,
            "pivotValues": [
                "urn:li:sponsoredCampaign:1234565"
            ]
        },
        {
            "dateRange": {
                "start": {
                    "month": 3,
                    "year": 2019,
                    "day": 21
                },
                "end": {
                    "month": 3,
                    "year": 2019,
                    "day": 21
                }
            },
            "clicks": 3,
            "impressions": 154,
            "pivotValues": [
                "urn:li:sponsoredCampaign:1323516"
            ]
        }
    ],
    "paging": {
        "count": 10,
        "start": 0,
        "links": []
    }
}

【问题讨论】:

  • "pivotvalues" 是否总是包含 1 个元素的列表?
  • 是的。只需要来自该元素的数据。
  • 对不起,我不清楚。我要问的是你会看到"pivotValues" = [value1, value2, value3]...还是总是,"pivotValues" = [value1]
  • 总是一个值
  • 太棒了。我在下面修复了我的解决方案(我仍然保留它,以防出现多个,但如果它只是 1,则不应影响输出)。这应该为你工作/清理它。

标签: python json python-3.x


【解决方案1】:

您可以使用json_normalize。唯一的问题是"pivotValues" 是一个列表。所以不确定你想要什么,或者这些列表中是否有超过 1 个元素。如果它只是一个元素,您可以轻松处理该列。如果它可以有多个元素,您可以为每个元素创建一个新行(这意味着您有多个具有相同数据的行,除了不同的pivotValues,或者您可以将每行扩展为每个pivotValues,但随后会这些列表具有不同长度的空值。

我还在那里添加了(看到pivotValues 都有相同的前缀),为您拆分帽子值以备不时之需。

鉴于:

data = {
    "elements": [
        {
            "dateRange": {
                "start": {
                    "month": 3,
                    "year": 2019,
                    "day": 3
                },
                "end": {
                    "month": 3,
                    "year": 2019,
                    "day": 3
                }
            },
            "clicks": 11,
            "impressions": 2453,
            "pivotValues": [
                "urn:li:sponsoredCampaign:1234567"
            ]
        },
        {
            "dateRange": {
                "start": {
                    "month": 3,
                    "year": 2019,
                    "day": 7
                },
                "end": {
                    "month": 3,
                    "year": 2019,
                    "day": 7
                }
            },
            "clicks": 1,
            "impressions": 629,
            "pivotValues": [
                "urn:li:sponsoredCampaign:1234565"
            ]
        },
        {
            "dateRange": {
                "start": {
                    "month": 3,
                    "year": 2019,
                    "day": 21
                },
                "end": {
                    "month": 3,
                    "year": 2019,
                    "day": 21
                }
            },
            "clicks": 3,
            "impressions": 154,
            "pivotValues": [
                "urn:li:sponsoredCampaign:1323516"
            ]
        }
    ],
    "paging": {
        "count": 10,
        "start": 0,
        "links": []
    }
}

代码:

import pandas as pd
from pandas.io.json import json_normalize


df = json_normalize(data['elements'])
df['pivotValues'] = df.pivotValues.apply(pd.Series).add_prefix('pivotValues_')
df['pivotValues_stripped'] = df['pivotValues'].str.rsplit(':',1, expand=True)[1]

df.to_csv('path/filename.csv', index=False)

输出:

print (results.to_string())
   clicks  dateRange.end.day  dateRange.end.month  dateRange.end.year  dateRange.start.day  dateRange.start.month  dateRange.start.year  impressions                       pivotValues pivotValues_stripped
0      11                  3                    3                2019                    3                      3                  2019         2453  urn:li:sponsoredCampaign:1234567              1234567
1       1                  7                    3                2019                    7                      3                  2019          629  urn:li:sponsoredCampaign:1234565              1234565
2       3                 21                    3                2019                   21                      3                  2019          154  urn:li:sponsoredCampaign:1323516              1323516

【讨论】:

  • 这个规范化的数据可以直接添加到数据库表中吗?
  • 我不明白为什么它不能。
【解决方案2】:

您可以使用以下命令在 python 中加载和解析 json:

import json
y = json.loads(x)

y 将是一个 python 字典。现在循环 y['elements'] 并创建一个包含所需字段的列表。例如提取开始和结束日期的年份:

list_for_csv=[]
for e in y['elements']:
    list_for_csv.append([e['daterange']['start']['year'],e['daterange']['end']['year']])

然后使用numpy保存为csv:

import numpy as np
for_csv = np.asarray(list_for_csv)
np.savetxt("your_file.csv", for_csv, delimiter=",")

【讨论】:

    猜你喜欢
    • 2018-10-27
    • 2021-05-17
    • 2019-09-24
    • 1970-01-01
    • 2017-05-02
    • 2020-12-04
    • 2018-12-08
    • 1970-01-01
    相关资源
    最近更新 更多