从嵌套字典列表获取pandas dataframe

6

我是新手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 

这是可能的吗?
5个回答

10

简单:

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

4

另一种解决方案:

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。你知道为什么吗?否则,我认为我理解这段代码的意图。 - aliki43
抱歉,我忘记指定导入。我正在使用标准库中的 itertools.chain。请参见编辑。 - Igor Raush
谢谢!我会尝试使用pd.concat和这个方法,因为我有很多数据需要处理。 - aliki43
快速更新一下:在处理 pd.concat 和这种方法之间,我没有看到任何时间上的巨大差异,可能是因为我的数据集不是那么庞大(总共有20,000个观测值)。再次感谢! - aliki43
我猜观察数量并不像“块”的数量那么重要。从每个“块”创建一个DataFrame并通过pd.concat进行繁琐的索引对齐会产生相当大的开销,但如果只有几个“块”,这就不太重要了。无论如何,很高兴你解决了问题。 - Igor Raush

1
你可以混合字典列表,以便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}]

0
[pd.DataFrame.from_dict(l, orient='index') for l in my_list]

文档中提到,如果你想要将字典的键作为行,请使用orient='index'


0
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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接