将字典列表转换为 pandas DataFrame

DataFrame()DataFrame.from_records().from_dict()

根据数据的结构和格式,有些情况下所有三种方法都适用,有些情况下某些方法比其他方法更好,有些情况下某些方法根本不起作用。

考虑一个非常复杂的例子:

np.random.seed(0)
data = pd.DataFrame(
    np.random.choice(10, (3, 4)), columns=list('ABCD')).to_dict('r')
print(data)
[{'A': 5, 'B': 0, 'C': 3, 'D': 3},
 {'A': 7, 'B': 9, 'C': 3, 'D': 5},
 {'A': 2, 'B': 4, 'C': 7, 'D': 6}]

这个列表由“记录”组成,每个键都在其中。这是你可能遇到的最简单的情况。

以下方法都会产生相同的输出:

pd.DataFrame(data)
pd.DataFrame.from_dict(data)
pd.DataFrame.from_records(data)
ABCD
5033
7935
2476

关于字典方向:orient=‘index’/‘columns’

在继续之前,重要的是要区分不同的字典方向类型,并了解 pandas 的支持情况。有两种主要类型:“columns”和“index”。

orient='columns'

具有“columns”方向的字典将它们的键对应到等效 DataFrame 中的列。

例如,上面的 data 处于“columns”方向。

data_c = [
    {'A': 5, 'B': 0, 'C': 3, 'D': 3},
    {'A': 7, 'B': 9, 'C': 3, 'D': 5},
    {'A': 2, 'B': 4, 'C': 7, 'D': 6}]
pd.DataFrame.from_dict(data_c, orient='columns')
ABCD
5033
7935
2476

注意:如果你使用 pd.DataFrame.from_records,则默认方向为“columns”(你不能指定其他方式),并且字典将相应地加载。

orient='index'

在这种方向下,键被假定为索引值。这种类型的数据最适合用于 pd.DataFrame.from_dict

data_i = {
    0: {'A': 5, 'B': 0, 'C': 3, 'D': 3},
    1: {'A': 7, 'B': 9, 'C': 3, 'D': 5},
    2: {'A': 2, 'B': 4, 'C': 7, 'D': 6}}
pd.DataFrame.from_dict(data_i, orient='index')
ABCD
5033
7935
2476

这种情况在原始问题中没有考虑,但仍然很有用。

设置自定义索引

如果你需要在生成的 DataFrame 上设置自定义索引,可以使用 index=... 参数。

pd.DataFrame(data, index=['a', 'b', 'c'])
# pd.DataFrame.from_records(data, index=['a', 'b', 'c'])
ABCD
a503
b793
c247

这不受 pd.DataFrame.from_dict 支持。

处理缺失的键/列

所有方法都可以开箱即用地处理带有缺失键/列值的字典。例如,

data2 = [
    {'A': 5, 'C': 3, 'D': 3},
    {'A': 7, 'B': 9, 'F': 5},
    {'B': 4, 'C': 7, 'E': 6}]

以下方法都会产生相同的输出:

pd.DataFrame(data2)
pd.DataFrame.from_dict(data2)
pd.DataFrame.from_records(data2)
ABCDEF
5.0NaN3.03.0NaNNaN
7.09.0NaNNaNNaN5.0
NaN4.07.0NaN6.0NaN

读取子集列

“如果我不想读取每一列怎么办?”你可以轻松地使用 columns=... 参数来指定这一点。

例如,从上面 data2 的示例字典中,如果你想只读取列“A”、“D”和“F”,可以通过传递一个列表来实现:

pd.DataFrame(data2, columns=['A', 'D', 'F'])
# pd.DataFrame.from_records(data2, columns=['A', 'D', 'F'])
ADF
5.03.0NaN
7.0NaN5.0
NaNNaNNaN

这不受默认 orient='columns'pd.DataFrame.from_dict 支持。

pd.DataFrame.from_dict(data2, orient='columns', columns=['A', 'B'])

ValueError:无法在 orient='columns' 下使用 columns 参数。

万能解决方案:json_normalize 用于嵌套数据**

一种强大且稳健的替代上述方法的方式是使用 json_normalize 函数,该函数可以处理字典列表(记录),并且还可以处理嵌套字典。

pd.json_normalize(data)
ABCD
0503
1793
2247
pd.json_normalize(data2)
ABCDE
05.0NaN33.0
1NaN4.07NaN

再次提醒,传递给 json_normalize 的数据需要采用字典列表(记录)格式。

正如前面提到的,json_normalize 还可以处理嵌套字典。以下是一个来自文档的例子:

data_nested = [
    {'counties': [{'name': 'Dade', 'population': 12345},
                  {'name': 'Broward', 'population': 40000},
                  {'name': 'Palm Beach', 'population': 60000}],
     'info': {'governor': 'Rick Scott'},
     'shortname': 'FL',
     'state': 'Florida'},
    {'counties': [{'name': 'Summit', 'population': 1234},
                  {'name': 'Cuyahoga', 'population': 1337}],
     'info': {'governor': 'John Kasich'},
     'shortname': 'OH',
     'state': 'Ohio'}
]
pd.json_normalize(data_nested,
                  record_path='counties',
                  meta=['state', 'shortname', ['info', 'governor']])
namepopulationstateshortnameinfo.governor
Dade12345FloridaFLRick Scott
Broward40000FloridaFLRick Scott
Palm Beach60000FloridaFLRick Scott
Summit1234OhioOHJohn Kasich
Cuyahoga1337OhioOHJohn Kasich

有关 metarecord_path 参数的更多信息,请参阅相关文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李星星BruceL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值