首页 > 解决方案 > 从嵌套字典结构列表(具有两个级别)创建数据框的 Pythonic 方法是什么?

问题描述

我收到以下格式的请求(我无法更改输入请求格式):

{  "inputs":
    [
       {
           "TimeGenerated": "datetimestring",
           "counters": {
               "counter1": float_value,
               "counter2": float_value,
               "counter3": float_value
            }
      },
      {
           "TimeGenerated": "datetimestring",
           "counters": {
               "counter1": float_value,
               "counter2": float_value,
               "counter3": float_value
            }
      },
      {
           "TimeGenerated": "datetimestring",
           "counters": {
               "counter1": float_value,
               "counter2": float_value,
               "counter3": float_value
           }
      }
    ]
}

我想用DataFrame这本字典创建一个列:TimeGenerated, counter1, counter2, counter3

DataFrame从这个嵌套字典列表中创建一个最有效的pythonic方法是什么?


可能的解决方案(不是最有效的)

我发现的解决方案是:

x = []
for i in input_json['inputs']:
        counters = i['counters']                   # We do not want counters in the column headers. This returns the dictionary { "counter1": float_value, "counter2": float_value, "counter3": float_value}
        counters['_time'] = i['TimeGenerated']     # The idea to extract it and then add it to the common dictionary. Counters would now be like { "counter1": float_value, "counter2": float_value, "counter3": float_value, "_time": "datetimestring"}
        x.append(counters)                         # Create a list of such dictionaries (with single level dictionaries without any nesting)
in_df = pd.DataFrame(x)                            # Create a Dataframe from the list
in_df['_time'] = pd.to_datetime(in_df['_time'])    # To convert datetimestring to datetime.

但是,我相信有更有效的方法可以实现这一目标!


类似的问题(具有不同的预期最终结果)

StackOverflow 上的其他一些问题解决了类似的问题(但预期会产生不同的结果)。添加它们以供在实际搜索另一个最终结果时偶然发现这一点的人细读(此外,将作为一个很好的比较点来使用 Python 字典、列表和数据帧以及它们如何相互关联)。

  1. Python Dataframe 包含字典列表,需要使用字典项创建新的 dataframe
  2. 从嵌套字典创建熊猫数据框,外部键作为 df 索引和内部键列标题
  3. 从嵌套字典创建数据框

标签: pythonpandaslistdataframedictionary

解决方案


假设所有子对象具有相同的结构,您可以从第一个开始列出键并将它们用于列。

columns = ['TimeGenerated', *j['inputs'][0]['counters'].keys()]
df = pd.DataFrame([[t['TimeGenerated'], *t['counters'].values()] for t in j['inputs']], columns=columns)

输出

>>> df
    TimeGenerated  counter1  counter2  counter3
0  datetimestring   123.456   123.456   123.456
1  datetimestring   123.456   123.456   123.456
2  datetimestring   123.456   123.456   123.456

推荐阅读