从嵌套字典列表中获取熊猫数据框

Posted

技术标签:

【中文标题】从嵌套字典列表中获取熊猫数据框【英文标题】:Getting pandas dataframe from list of nested dictionaries 【发布时间】:2017-06-16 06:15:36 【问题描述】:

我是 Python 新手,所以这可能很简单,但是在寻找了一段时间后,我无法为我的问题找到一个好的答案。我正在尝试从字典列表中创建一个 Pandas 数据框。

我的嵌套字典列表如下:

my_list = [0: 'a': '23', 'b': '15', 'c': '5', 'd': '-1', 
            1: 'a': '5', 'b': '6', 'c': '7', 'd': '9', 
            2: 'a': '9', 'b': '15', 'c': '5', 'd': '7', 
           0: 'a': '5', 'b': '249', 'c': '92', 'd': '-4', 
            1: 'a': '51', 'b': '5', 'c': '34', 'd': '1', 
            2: 'a': '3', 'b': '8', 'c': '3', 'd': '11']

所以主字典中的每个键都有 3 个值。

使用data = pd.DataFrame(my_list) 将它们放入数据框中会返回一些不可用的东西,因为每个单元格中都有关于 a、b、c 和 d 的信息。

我想最终得到一个如下所示的数据框:

 name| a  | b  | c | d 
0    | 23 | 15 | 5 | -1 
1    | 5  | 6  | 7 |  9 
2    | 9  | 15 | 5 |  7 
0    | 5  |249 | 92| -4 
1    |51  | 5  | 34|  1 
2    | 3  | 8  | 3 | 11 

这可能吗?

【问题讨论】:

【参考方案1】:

简单:

pd.concat([pd.DataFrame(l) for l in my_list],axis=1).T

【讨论】:

【参考方案2】:

另一种解决方案:

from itertools import chain
pd.DataFrame.from_items(list(chain.from_iterable(d.iteritems() for d in my_list))).T

在我的实验中,这比使用 pd.concat 更快(尤其是当“子数据帧”的数量很大时),但代价是更冗长。

【讨论】:

非常感谢!当我尝试此代码时,我收到错误:NameError: name 'chain' is not defined。你知道为什么吗?否则,我想我理解这段代码的直觉。 抱歉,忘记指定导入。我使用的是itertools.chain,它是标准库的一部分。请参阅编辑。 谢谢!我会尝试 pd.concat 和这个,因为我确实有很多数据要处理。 只是一个快速更新:我没有看到 pd.concat 和这种方法在处理时间方面有任何巨大差异,可能是因为我的数据集不是那么大(总共 20,000 次观察)。再次感谢您! 我猜观察的数量并不像“块”的数量那么重要。从每个块创建一个DataFrame,然后与pd.concat 进行繁琐的索引对齐会有相当大的开销,但如果你只有几个块,这并不重要。无论如何,很高兴你解决了你的问题。【参考方案3】:

您可以调整字典列表以供 DataFrame 构造函数接受:

In [4]: pd.DataFrame.from_records(['name': k, **v for d in my_list for k,v in d.items()])
Out[4]:
    a    b   c   d  name
0  23   15   5  -1     0
1   5    6   7   9     1
2   9   15   5   7     2
3   5  249  92  -4     0
4  51    5  34   1     1
5   3    8   3  11     2

In [5]: df = pd.DataFrame.from_records(['name': k, **v for d in my_list for k,v in d.items()])

In [6]: df.set_index('name',inplace=True)

In [7]: df
Out[7]:
       a    b   c   d
name
0     23   15   5  -1
1      5    6   7   9
2      9   15   5   7
0      5  249  92  -4
1     51    5  34   1
2      3    8   3  11

这需要相对较新版本的 Python,'name':'something', **rest 才能工作。它只是以下内容的简写:

In [13]: reshaped = []
    ...: for d in my_list:
    ...:     for k, v in d.items():
    ...:         new = 'name': k
    ...:         new.update(v)
    ...:         reshaped.append(new)
    ...:

In [14]: reshaped
Out[14]:
['a': '23', 'b': '15', 'c': '5', 'd': '-1', 'name': 0,
 'a': '5', 'b': '6', 'c': '7', 'd': '9', 'name': 1,
 'a': '9', 'b': '15', 'c': '5', 'd': '7', 'name': 2,
 'a': '5', 'b': '249', 'c': '92', 'd': '-4', 'name': 0,
 'a': '51', 'b': '5', 'c': '34', 'd': '1', 'name': 1,
 'a': '3', 'b': '8', 'c': '3', 'd': '11', 'name': 2]

【讨论】:

【参考方案4】:
from pandas import DataFrame

def flat_dict(data: dict, prefix=''):
    result = dict()
    
    for key in data:
        
        if len(prefix):
            field = prefix + '_' + key
        else:
            field = key
            
        if isinstance(data[key], dict):
            result.update(
                flat_dict(data[key], key)
            )
        else:
            result[field] = data[key]
    
    return result

refactor_data = map(lambda x: flat_dict(x), data)

df = DataFrame(refactor_data)

【讨论】:

以上是关于从嵌套字典列表中获取熊猫数据框的主要内容,如果未能解决你的问题,请参考以下文章

从熊猫数据框中提取嵌套字典

从嵌套字典构造熊猫多索引数据框

嵌套熊猫数据框 - 如何按数据选择/分组?

从熊猫数据框创建嵌套字典

如何使用熊猫从嵌套字典创建数据框?

我想将国家/地区列表与作为熊猫数据框 Python 中字典对象类型的列数据进行比较