【问题标题】:json_normalize- Nested dictionary to pandas DataFramejson_normalize- 嵌套字典到 pandas DataFrame
【发布时间】:2022-01-02 14:51:47
【问题描述】:

需要以下嵌套字典的帮助,我想将其转换为 pandas 数据框

我的 JSON 有以下 CPU 数据实例并且随机出现:

Instance1 [{'datapoints': [{'statistic': 'Minimum', 'timestamp': '2021-08-31 06:50:00.000000', 'value': 59.03}, {'statistic': 'Minimum', 'timestamp': '2021-08-18 02:50:00.000000', 'value': 59.37}, {'statistic': 'Minimum', 'timestamp': '2021-08-24 16:50:00.000000', 'value': 58.84},, 'metric': 'VolumeIdleTime', 'unit': 'Seconds'}]

Instance2 [{'datapoints': [{'statistic': 'Minimum', 'timestamp': '2021-08-31 06:50:00.000000', 'value': 60}, {'statistic': 'Minimum', 'timestamp': '2021-08-18 02:50:00.000000', 'value': 55.45}, {'statistic': 'Minimum', 'timestamp': '2021-08-24 16:50:00.000000', 'value': 54.16}, {'statistic': 'Minimum', 'timestamp': '2021-08-06 07:50:00.000000', 'value': 50.03}, {'statistic': 'Minimum', 'timestamp': '2021-08-04 22:50:00.000000', 'value': 60}, {'statistic': 'Minimum', 'timestamp': '2021-08-26 01:50:00.000000', 'value': 60.34}, 'metric': 'VolumeIdleTime', 'unit': 'Seconds'}]

Instance3 [{'datapoints': [{'statistic': 'Minimum', 'timestamp': '2021-08-31 06:50:00.000000', 'value': 60}, {'statistic': 'Minimum', 'timestamp': '2021-08-18 02:50:00.000000', 'value': 38.12}, {'statistic': 'Minimum', 'timestamp': '2021-08-24 16:50:00.000000', 'value': 42.31}, {'statistic': 'Minimum', 'timestamp': '2021-08-06 07:50:00.000000', 'value': 45.22}, {'statistic': 'Minimum', 'timestamp': '2021-08-04 22:50:00.000000', 'value': 40.51}, {'statistic': 'Minimum', 'timestamp': '2021-08-26 01:50:00.000000', 'value': 34.35}, {'statistic': 'Minimum', 'timestamp': '2021-08-11 12:50:00.000000', 'value': 46.33},'metric': 'VolumeIdleTime', 'unit': 'Seconds'}]

And many more instance details to follow ( Close to 8K instance information )

问题:如何推进下面的编码,以便它可以从每个实例的所有行中获取:

data = [{'datapoints': [{'statistic': 'Minimum', 'timestamp': '2021-08-31 06:50:00.000000', 'value': 59.03},{'statistic': 'Minimum', 'timestamp': '2021-08-18 02:50:00.000000', 'value': 59.37}, {'statistic': 'Minimum', 'timestamp': '2021-08-24 16:50:00.000000', 'value': 58.84}],'metric': 'VolumeIdleTime', 'unit': 'Seconds'}]
df = pd.json_normalize(data, record_path="datapoints", meta=["metric", "unit"])
print(df)

【问题讨论】:

    标签: python pandas dataframe dictionary


    【解决方案1】:

    我不太明白问题出在哪里,但如果您的方法不适用于所有行,请执行以下操作:

    如果您的数据如下所示:

    data = [{'datapoints': [{'statistic': 'Minimum', 'timestamp': '2021-08-31 06:50:00.000000', 'value': 59.03},{'statistic': 'Minimum', 'timestamp': '2021-08-18 02:50:00.000000', 'value': 59.37}, {'statistic': 'Minimum', 'timestamp': '2021-08-24 16:50:00.000000', 'value': 58.84}],'metric': 'VolumeIdleTime', 'unit': 'Seconds'}]
    df = pd.DataFrame(data)
    

    即:

                                       datapoints          metric     unit
    0  [{'statistic': 'Minimum', 'timestamp': '2021-0...  VolumeIdleTime  Seconds
    
    

    你可以定义如下函数:

    def flatten_nested_json_df(df):
        df = df.reset_index()
        s = (df.applymap(type) == list).all()
        list_columns = s[s].index.tolist()
        
        s = (df.applymap(type) == dict).all()
        dict_columns = s[s].index.tolist()
    
        
        while len(list_columns) > 0 or len(dict_columns) > 0:
            new_columns = []
    
            for col in dict_columns:
                horiz_exploded = pd.json_normalize(df[col]).add_prefix(f'{col}.')
                horiz_exploded.index = df.index
                df = pd.concat([df, horiz_exploded], axis=1).drop(columns=[col])
                new_columns.extend(horiz_exploded.columns) # inplace
    
            for col in list_columns:
                #print(f"exploding: {col}")
                df = df.drop(columns=[col]).join(df[col].explode().to_frame())
                new_columns.append(col)
    
            s = (df[new_columns].applymap(type) == list).all()
            list_columns = s[s].index.tolist()
    
            s = (df[new_columns].applymap(type) == dict).all()
            dict_columns = s[s].index.tolist()
        return df
    

    并应用它:

    flatten_nested_json_df(df)
    

    返回:

    index          metric     unit datapoints.statistic  \
    0      0  VolumeIdleTime  Seconds              Minimum   
    0      0  VolumeIdleTime  Seconds              Minimum   
    0      0  VolumeIdleTime  Seconds              Minimum   
    
             datapoints.timestamp  datapoints.value  
    0  2021-08-31 06:50:00.000000             59.03  
    0  2021-08-18 02:50:00.000000             59.37  
    0  2021-08-24 16:50:00.000000             58.84  
    

    【讨论】:

    • 与定义的函数相关的后续问题:如果选择 10 行,编码工作正常:例如 Less_metric=met_data_aug.iloc[:10,:] flatten_nested_json_df(Less_metric) # 解析在所有层工作并提取所有列如果我选择 1000 行:eg- med_metric=met_data_aug.iloc[:1000,:] flatten_nested_json_df(med_metric) # 它没有完全解析并且没有提取所有列数据请帮助!!
    【解决方案2】:

    以下代码将遍历所有实例并将它们全部连接到一个大数据帧:

    import pandas as pd
    
    df = pd.json_normalize(instance1, record_path="datapoints", meta=["metric", "unit"])
    for instance in your_remained_instances:
      df = pd.concat([df, pd.json_normalize(instance, record_path="datapoints", meta=["metric", "unit"])])
    
    

    【讨论】:

    • 实例上的任何 NAN 值或列差异都会导致编码中断?如何解决这个问题? - 请指导!如您所知,它的代码没有完全去规范化 . index metrics.metric metrics.unit metrics.datapoints 0 13445 VolumeIdleTime Seconds {'statistic': 'Minimum', 'timestamp': '2021-08-07 18:40:00.000000', 'value': 59.98}
    猜你喜欢
    • 1970-01-01
    • 2019-11-15
    • 2022-01-01
    • 2017-12-26
    • 2015-08-03
    • 2019-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多