将嵌套的JSON数据查看为pandas数据框。

5

我现在已经将当前的问题添加到了GitHub上。请查找存储库的URL。我还包括了一个Jupyter笔记本,其中也解释了这个问题。谢谢大家。

https://github.com/simongraham/dataExplore.git


我目前正在处理一个与营养相关的项目,其中数据以原始JSON格式存储。我想使用Python和Pandas获取一个易于理解的数据框架。我知道当JSON不是嵌套的时候,这是一个简单的任务。在这种情况下,我会使用:

nutrition = pd.read_json('data')

然而,我有嵌套信息,很难将其放入合理的数据框中。JSON格式如下,其中nutritionNutrients元素本身是一个嵌套元素。此元素的嵌套描述了各种内容的营养成分,例如包括酒精和bcfa。由于这是一个大型数据文件,因此仅包含样例。
  [
        {
            "vcNutritionPortionId": "478d1905-f264-4d9b-ab76-0ed4252193fd",
            "vcNutritionId": "2476378b-79ee-4857-a81d-489661a039a1",
            "vcUserId": "cc51145b-5a70-4344-9b55-1a4455f0a9d2",
            "vcPortionId": "1",
            "vcPortionName": "1 average pepper",
            "vcPortionSize": "20",
            "ftEnergyKcal": 5.2,
            "vcPortionUnit": "g",
            "dtConsumedDate": "2016-05-04T00:00:00",
            "nutritionNutrients": [
                {
                    "vcNutritionPortionId": "478d1905-f264-4d9b-ab76-0ed4252193fd",
                    "vcNutrient": "alcohol",
                    "ftValue": 0,
                    "vcUnit": "g",
                    "nPercentRI": 0,
                    "vcTrafficLight": ""
                },
                {
                    "vcNutritionPortionId": "478d1905-f264-4d9b-ab76-0ed4252193fd",
                    "vcNutrient": "bcfa",
                    "ftValue": 0,
                    "vcUnit": "g",
                    "nPercentRI": 0,
                    "vcTrafficLight": ""
                },
                {
                    "vcNutritionPortionId": "478d1905-f264-4d9b-ab76-0ed4252193fd",
                    "vcNutrient": "biotin",
                    "ftValue": 0,
                    "vcUnit": "µg",
                    "nPercentRI": 0,
                    "vcTrafficLight": ""
                },
                ...
            ]
        }
    ]

希望得到任何帮助。

谢谢。

.... ....

现在我已经找到了使用json_normalize解决这个问题的方法,但是这次我的代码嵌套了两次。也就是说:

[
{
...
}
[,
"nutritionPortions": [
    {
        "vcNutritionPortionId": "478d1905-f264-4d9b-ab76-0ed4252193fd",
        "vcNutritionId": "2476378b-79ee-4857-a81d-489661a039a1",
        "vcUserId": "cc51145b-5a70-4344-9b55-1a4455f0a9d2",
        "vcPortionId": "1",
        "vcPortionName": "1 average pepper",
        "vcPortionSize": "20",
        "ftEnergyKcal": 5.2,
        "vcPortionUnit": "g",
        "dtConsumedDate": "2016-05-04T00:00:00",
        "nutritionNutrients": [
            {
                "vcNutritionPortionId": "478d1905-f264-4d9b-ab76-0ed4252193fd",
                "vcNutrient": "alcohol",
                "ftValue": 0,
                "vcUnit": "g",
                "nPercentRI": 0,
                "vcTrafficLight": ""
            },
            {
                "vcNutritionPortionId": "478d1905-f264-4d9b-ab76-0ed4252193fd",
                "vcNutrient": "bcfa",
                "ftValue": 0,
                "vcUnit": "g",
                "nPercentRI": 0,
                "vcTrafficLight": ""
            },
            {
                "vcNutritionPortionId": "478d1905-f264-4d9b-ab76-0ed4252193fd",
                "vcNutrient": "biotin",
                "ftValue": 0,
                "vcUnit": "µg",
                "nPercentRI": 0,
                "vcTrafficLight": ""
            },
            ...
           }
          ]
        }
      ]

当我有一个仅包含营养数据的JSON时,我可以使用以下方法:
nutrition = (pd.io
   .json
   .json_normalize((data, ['nutritionPortions']), 'nutritionNutrients',
        ['vcNutritionId','vcUserId','vcPortionId','vcPortionName','vcPortionSize',
         'ftEnergyKcal','vcPortionUnit','dtConsumedDate'])
)

然而,我的数据不仅包含营养信息。例如,它会包含活动信息,因此营养信息在开头嵌套了“nutrtitionPortions”。假设所有其他列都不是嵌套的,它们由“Activity”和“Wellbeing”表示。
如果我使用以下代码:
nutrition = (pd.io
   .json
   .json_normalize(data, ['nutritionPortions'])
)

我将回归最初的问题,即“nutritionNutrients”嵌套的位置,但是我无法成功地获取相应的数据框架。
谢谢。
1个回答

4

更新:这应该适用于您的kaidoData.json文件:

df = (pd.io
        .json
        .json_normalize(data[0]['ionPortions'], 'nutritionNutrients',
            ['vcNutritionId','vcUserId','vcPortionId','vcPortionName','vcPortionSize',
             'dtCreatedDate','dtUpdatedDate','nProcessingStatus',
             'vcPortionUnit','dtConsumedDate'
            ]
        )
)

PS我不知道'ftEnergyKcal'出了什么问题 - 它抛出了一个错误:

KeyError:'ftEnergyKcal'

也许在某些部分中它丢失了

旧答案:

使用json_normalize()

(pd.io
   .json
   .json_normalize(l, 'nutritionNutrients',
        ['vcNutritionId','vcUserId','vcPortionId','vcPortionName','vcPortionSize',
         'ftEnergyKcal','vcPortionUnit','dtConsumedDate'])
)

演示:

In [107]: (pd.io
   .....:    .json
   .....:    .json_normalize(l, 'nutritionNutrients',
   .....:         ['vcNutritionId','vcUserId','vcPortionId','vcPortionName','vcPortionSize',
   .....:          'ftEnergyKcal','vcPortionUnit','dtConsumedDate'])
   .....: )
Out[107]:
   ftValue  nPercentRI vcNutrient vcNutritionPortionId vcTrafficLight        ...        vcPortionSize  \
0        0           0    alcohol  478d1905-f264-4d...                       ...                   20
1        0           0       bcfa  478d1905-f264-4d...                       ...                   20
2        0           0     biotin  478d1905-f264-4d...                       ...                   20

         vcNutritionId vcPortionId ftEnergyKcal     vcPortionName
0  2476378b-79ee-48...           1          5.2  1 average pepper
1  2476378b-79ee-48...           1          5.2  1 average pepper
2  2476378b-79ee-48...           1          5.2  1 average pepper

[3 rows x 14 columns]

其中l是您的列表(解析的JSON)


1
@simongraham,我很高兴能够帮助您。 :) 请考虑接受最有帮助的答案 - 这也将表明您的问题已得到解答。 - MaxU - stand with Ukraine
我不知道你是否能帮我一下,看看我最新修改的问题。谢谢 :) - simongraham
@simongraham,我认为你需要传递类似于data['nutritionPortions']而不是datajson_normalize函数。 - MaxU - stand with Ukraine
很抱歉,@MaxU,我已经尝试过这个方法了,但不幸的是没有成功。我想我需要一种获取原始JSON数据子集的方法。 - simongraham
@simongraham,我建议你打开另一个问题并放置一个__可运行__的数据示例。例如:data = [...],可以在Python中执行而不会出现错误。或者,您可以将数据上传到某个地方并在问题中发布该文件的链接... - MaxU - stand with Ukraine
我已将相关数据添加到 https://github.com/simongraham/dataExplore.git。我还添加了一个Jupyter笔记本。随意尝试使用 :) @MaxU - simongraham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接