【问题标题】:Any depth nested dict to pandas dataframe任何深度嵌套字典到熊猫数据框
【发布时间】:2022-11-17 22:11:30
【问题描述】:

我一直在努力摆脱嵌套的深度字典丁到熊猫数据框。

我已经尝试使用递归函数,如下所示,但我的问题是,当我迭代 KEY 时,我不知道之前的密钥是什么。

我也尝试过使用 json.normalize,来自 dict 的 pandas,但我总是在列中以点结束......

示例代码:

def iterate_dict(d, i = 2, cols = []):
    
    for k, v in d.items():
        # missing here how to check for the previous key
        # so that I can create an structure to create the dataframe.
        if type(v) is dict:   
            print('this is k: ', k)  
            if i % 2  == 0:
                cols.append(k)
            i+=1
            iterate_dict(v, i, cols)            
        else:
            print('this is k2: ' , k, ': ', v)

  
iterate_dict(test2)

这是我的字典的一个例子:

# example 2 
test = {
    'column-gender': {
        'male': {
            'column-country' : {
                'FRENCH': {
                    'column-class': [0,1]
                },
                ('SPAIN','ITALY') : {
                    'column-married' : {
                        'YES': {
                            'column-class' : [0,1]
                        },
                        'NO' : {
                            'column-class' : 2
                        }
                    }
                }
            }
        },
        'female': {
            'column-country' : {
                ('FRENCH', 'SPAIN') : {
                    'column-class' : [[1,2],'#']
                },
                'REST-OF-VALUES': {
                    'column-married' : '*'
                }
            }
        }
    }
}

这就是我希望数据框的样子:

欢迎任何建议:)

【问题讨论】:

    标签: python json pandas dictionary nested


    【解决方案1】:

    我不确定这些数据如何保持一致,但为了理解我们可以做类似下面的事情,请记住这只是一个关于我们如何处理它的方法的小演示,你可以花更多时间来完善它因此:

    为了更好地理解,我在每个步骤中都添加了 cmets。

    import pandas as pd
    
    
    def nested_dict_to_df(data, columns=None):
    
        if columns are None:
            columns = []
    
        # if the data is a dictionary, then we need to iterate over the keys
        if isinstance(data, dict):
    
            for key, value in data.items():
                columns.append(key)
                yield from nested_dict_to_df(value, columns)  # recursive call
                columns.pop()  # remove the last element
        else:
            yield columns + [data]
    
    
    df = pd.DataFrame(nested_dict_to_df(data))
    
    # Drop column [0, 2, 4, 6] from the dataframe that are not needed for the final output
    df = df.drop(df.columns[[0, 2, 4, 6]], axis=1)
    
    header = ["GENDER", "COUNTRY", "CLASS", "MARRIED"]  # Desired header
    df.columns = header
    
    print(df)
    

    输出:

       GENDER          COUNTRY        CLASS MARRIED
    0    male           FRENCH       [0, 1]    None
    1    male   (SPAIN, ITALY)          YES  [0, 1]
    2    male   (SPAIN, ITALY)           NO       2
    3  female  (FRENCH, SPAIN)  [[1, 2], #]    None
    4  female   REST-OF-VALUES            *    None
    

    【讨论】:

      【解决方案2】:

      如果列键始终以 column- 为前缀,则可以创建递归函数:

      def data_to_df(data):
          rec_out = []
          columns = []
          def dict_to_rec(d, depth=0, curr_row={}):
              for k, v in d.items():
                  if 'column-' in k: # definition of a column
                      columns.append(k[7:])
                      if isinstance(v, dict):
                          for val, nested_dict in v.items():
                              dict_to_rec(nested_dict, depth+1, dict(curr_row, **{columns[depth]: val}))
                      else:
                          rec_out.append(dict(curr_row, **{columns[depth]: v}))
          dict_to_rec(data)
          return pd.DataFrame(rec_out)
      
      print(data_to_df(test))
      

      输出:

         gender          country        class married
      0    male           FRENCH       [0, 1]     NaN
      1    male   (SPAIN, ITALY)          YES  [0, 1]
      2    male   (SPAIN, ITALY)           NO       2
      3  female  (FRENCH, SPAIN)  [[1, 2], #]     NaN
      4  female   REST-OF-VALUES            *     NaN
      

      【讨论】:

        猜你喜欢
        • 2023-03-23
        • 2018-04-14
        • 1970-01-01
        • 1970-01-01
        • 2021-02-15
        • 2019-03-26
        • 1970-01-01
        • 2017-12-23
        相关资源
        最近更新 更多