首页 > 解决方案 > DataFrame 将 json 列表扩展为多行

问题描述

我想知道是否有一种简洁的pythonic方式来做到这一点

  电话
0 {"brand":{"type":"android"},"names":[{"id":"1", "name":"a-1"},{"id":"2", “名称”:“a-2”}]}
1 {"brand":{"type":"iphone"},"names":[{"id":"3", "name":"i-1"},{"id":"4", “名称”:“i-2”}]}

我想将 json 字段扩展为数据字段,以获得以下信息:

   类型 ID 名称
0 机器人 1 a-1
1 机器人 2 a-2
2 苹果手机 3 i-1
3 iphone 4 i-2  


我找到了一个很好的解决方案:
def parser_expand_json(数据):
    键= []
    值 = []
    输入数据:
        键.附加(键)
        values.append(data.get(key))

    返回 pd.Series(值,索引 = 键)

# 这就对了
定义测试():
    data = [{'brand': {'type': 'android'}, 'names': [{'id': '1', 'name': 'a-1'}, {'id': '2 ', '名称': 'a-2'}]},
            {'brand': {'type': 'iphone'}, 'names': [{'id': '3', 'name': 'i-1'}, {'id': '4', '名称':'i-2'}]}]
    df = pd.DataFrame(数据)

    # 将 json 列表扩展为 N 行
    df = df.merge(df['names'].apply(pd.Series), right_index=True, left_index=True).drop('names', axis=1).melt(
        id_vars=['brand'], value_name='names').drop('variable', axis=1)

    """
                       品牌名称
    0 {u'type': u'android'} {u'id': u'1', u'name': u'a-1'}
    1 {u'type': u'iphone'} {u'id': u'3', u'name': u'i-1'}
    2 {u'type': u'android'} {u'id': u'2', u'name': u'a-2'}
    3 {u'type': u'iphone'} {u'id': u'4', u'name': u'i-2'}
    """
    打印df

    # 将 json 键扩展为列名
    df = pd.concat([df, df['brand'].apply(parser_expand_json), df['names'].apply(parser_expand_json)], axis=1).drop(
        ['品牌','名称'],轴=1)

    """
          类型 ID 名称
    0 机器人 1 a-1
    1 苹果手机 3 i-1
    2 机器人 2 a-2
    3 iphone 4 i-2
    """
    打印df

标签: pythonpandas

解决方案


使用列表手动构建具有所需结构的新 DataFrame 的解决方案:

import pandas as pd

json = [
  {"brand":{"type":"android"},"names":[{"id":"1", "name":"a-1"},{"id":"2", "name":"a-2"}]},
  {"brand":{"type":"iphone"},"names":[{"id":"3", "name":"i-1"},{"id":"4", "name":"i-2"}]}
  ]

json_data = {'phone': json}

df_1 = pd.DataFrame(json_data)

type_list = []
id_list = []
name_list = []

for row in df_1.phone:
    for item in row['names']:
        type_list.append(row['brand']['type'])
        id_list.append(item['id'])
        name_list.append(item['name'])

data = {'type':type_list, 'id':id_list, 'name':name_list}

df_2 = pd.DataFrame(data)

要使用json_normalize(),我们必须首先将 json 重构为所需的列结构。这种情况下的解决方案如下所示:

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

json = [
  {"brand":{"type":"android"},"names":[{"id":"1", "name":"a-1"},{"id":"2", "name":"a-2"}]},
  {"brand":{"type":"iphone"},"names":[{"id":"3", "name":"i-1"},{"id":"4", "name":"i-2"}]}
  ]

json_mod = []
for row in json:
    for item in row['names']:
        json_mod.append({'type':row['brand']['type'],'id':item['id'],'name':item['name']})

df_3 = json_normalize(json_mod)

df_2两者df_3都显示为:

  id name     type
0  1  a-1  android
1  2  a-2  android
2  3  i-1   iphone
3  4  i-2   iphone

推荐阅读