Pandas json_normalize:从数组中的对象访问数据

Pandas json_normalize:从数组中的对象访问数据,pandas,Pandas,我需要从JSON“列表”提取大量信息到数据帧 考虑以下JSON文件: { "List": [ { "Name": "xml", "CreateTime": "2020-11-13T10:44:20", "Descriptor": { "Loc

我需要从JSON“列表”提取大量信息到数据帧

考虑以下JSON文件:

{
    "List": [
        {
            "Name": "xml",
            "CreateTime": "2020-11-13T10:44:20",
            "Descriptor": {
                "Location": "some/url",
                ...
            }
            "Permissions": [
                {
                    "Principal": {
                        "Identifier": "ALLOWED_PRINCIPALS"
                    },
                    "Example": [
                        "ALL"
                    ]
                }
            ],
        },
        ...
    ]
}
我使用以下python代码将此json中的信息提取到熊猫数据帧中:

for List in response['List']:
    df = pd.json_normalize(response['List'])
    df = df.reindex(columns=['Name','CreateTime','Descriptor.Location','Permissions[Identifier]'])
前三列的填充没有问题,但我在访问存储在

  • 库({}括号):例如“权限[标识符]”和
  • 数组([]括号):例如“权限[示例]”
其他列填充数据帧,而我只得到标识符和示例的NULL。 我还尝试指定:Permissions['Identifier'],但在我的示例中,这将是一个语法错误

第二个示例:嵌套库中的数组

{
    "Table": [
        {
            "TableName": "data",
            "Descriptor": {
                "Columns": [
                    {
                        "Name": "category",
                        "Type": "string"
                    },
                    {
                        "Name": "author",
                        "Type": "string"
                    },
                    {
                        "Name": "title",
                        "Type": "string"
                    },
                    ...
在本例中,我试图访问“描述符”->“列”下的多个“名称”列的值

在第一部分中使用Jonathan Leon的解决方案,我为第二个示例尝试了以下代码:

for DatabaseList in db_response['Table']:
    df = pd.json_normalize(db_response['Table'], record_path=['Descriptor.Columns'], 
                        meta=['TableName', ['Descriptor.Columns']])
    df = df.reindex(columns=['TableName','Name'])
    
不幸的是,这样定义记录路径是不可能的。我必须以某种方式定义一个嵌套的记录路径来访问“列”中的数据

我还必须将record_前缀添加到json_normalize部分,因为有多个“Name”列


在我的示例中,使用python代码访问库和数组数据的正确语法是什么?

根据您提供的截断列表,这应该可以让您开始。json_规范化的文档是。对于多层列表,您可能需要循环和连接数据帧

df = pd.json_normalize(response['List'], record_path=['Permissions'], meta=['Name', 'CreateTime', ['Descriptor', 'Location']],
                        meta_prefix='', record_prefix='')
df = df.reindex(columns=['Name','CreateTime','Descriptor.Location','Principal.Identifier', 'Example'])
df.rename(columns={'Principal.Identifier':'Permissions.Identifier'})
pd.concat([ df, df['Example'].apply(pd.Series)], axis = 1)
输出(我修改了示例列表以说明如何扩展值):


根据您提供的截断列表,这应该可以让您开始。json_规范化的文档是。对于多层列表,您可能需要循环和连接数据帧

df = pd.json_normalize(response['List'], record_path=['Permissions'], meta=['Name', 'CreateTime', ['Descriptor', 'Location']],
                        meta_prefix='', record_prefix='')
df = df.reindex(columns=['Name','CreateTime','Descriptor.Location','Principal.Identifier', 'Example'])
df.rename(columns={'Principal.Identifier':'Permissions.Identifier'})
pd.concat([ df, df['Example'].apply(pd.Series)], axis = 1)
输出(我修改了示例列表以说明如何扩展值):


对于第二个例子,这应该让您开始

response = {
    "Table": [
        {
            "TableName": "data",
            "Descriptor": {
                "Columns": [
                    {
                        "Name": "category",
                        "Type": "string"
                    },
                    {
                        "Name": "author",
                        "Type": "string"
                    },
                    {
                        "Name": "title",
                        "Type": "string"
                    }]}}]}

cols = response['Table'][0]['Descriptor']['Columns']
df = pd.DataFrame(cols)
df.drop('Type', axis=1, inplace=True)
df['TableName'] = response['Table'][0]['TableName']

对于第二个例子,这应该让您开始

response = {
    "Table": [
        {
            "TableName": "data",
            "Descriptor": {
                "Columns": [
                    {
                        "Name": "category",
                        "Type": "string"
                    },
                    {
                        "Name": "author",
                        "Type": "string"
                    },
                    {
                        "Name": "title",
                        "Type": "string"
                    }]}}]}

cols = response['Table'][0]['Descriptor']['Columns']
df = pd.DataFrame(cols)
df.drop('Type', axis=1, inplace=True)
df['TableName'] = response['Table'][0]['TableName']

是的,我注意到这两种情况都适用。非常感谢您花时间为我的示例编写代码。您介意看看另一个我遇到麻烦的案例吗?@ire很高兴它对您有用。在你的另一个问题上贴上你尝试过的内容。最好让多个人有机会回答。我已经在我的主要帖子中添加了第二部分。是的,我注意到这两种情况都适用。非常感谢您花时间为我的示例编写代码。您介意看看另一个我遇到麻烦的案例吗?@ire很高兴它对您有用。在你的另一个问题上贴上你尝试过的内容。最好是让多个人都有机会回答。我已经在我的主要帖子中添加了第二部分。这确实让我开始了,我知道了如何获取我想要的数据:)非常感谢,我开始了,我知道了如何获取我想要的数据:)非常感谢