如何从具有多个具有嵌套值的字典的列表创建熊猫数据帧?



Python仍然很新,我正在尝试弄清楚如何从我创建的字典列表中创建格式正确的DataFrame。

listOutput = 
[{0: ['Name', val1, val2, val3, val4, val5]}, 
{1: ['Name', val1, val2, val3, val4, val5]}]

变成这样的东西:

0               1 
0  Name1            Name2
1  val1             val1
2  val2             val2
3  val3             val3
4  val4             val4
5  val5             val5

当我只从一个列表制作数据帧时,它的格式正确,但是当我使用字典从列表中创建一个数据帧时,它会输出如下内容:

0                                                  1
0  [Name1, 7995, 138.5, 300.0, 50.0, 7506.5] NaN                                   
1  NaN                                              [Name2, 7995,138.5, 300.0, 50.0, 75...

使用字典理解来合并字典:

import pandas as pd
df = pd.DataFrame({k:v for d in listOutput for k,v in d.items()})

使用collections.ChainMap的替代方法(速度稍慢):

from collections import ChainMap
import pandas as pd
df = pd.DataFrame(dict(ChainMap(*listOutput)))

输出:

0     1
0  Name  Name
1  val1  val1
2  val2  val2
3  val3  val3
4  val4  val4
5  val5  val5

由于列表中的每个字典都表示一列及其标题,因此您可以沿 axis=1 使用 pd.concat

pd.concat([pd.DataFrame(x) for x in listOutput], axis=1)

解释: 2 部分:在列表理解中创建数据帧 + pd.concat()

  1. 在列表推导中,您可以遍历输入列表的每个元素listOutput。此列表中的每个元素都是一个字典,其中有一个键和一个列表作为值。创建数据帧时,可以精确使用其中键 ->列名、值 ->列数据。 考虑您的列表如下所示:
listOutput = [{0: ['Name', 'val1', 'val2', 'val3']}, 
{1: ['Name', 'val4', 'val5', 'val6']}]

在迭代期间创建的两个 DF 如下所示:

#first iteration (e.g df1):
pd.DataFrame({0: ['Name', 'val1', 'val2', 'val3']})
0
0  Name
1  val1
2  val2
3  val3
# second iteration (e.g df2):
pd.DataFrame({1: ['Name', 'val4', 'val5', 'val6']})
1
0  Name
1  val4
2  val5
3  val6
  1. 这 2 个 df 存储在一个列表中并传递给pd.concataxis=1表示沿列串联。它期望获得"系列或数据帧对象的序列或映射"(->文档),这里有一系列数据帧对象。 我们没有在循环期间将 dfs 分配给变量(因为我们不需要),但考虑到你会命名它们(就像我上面在括号中所做的那样),然后在最后一步连接 dfs 将如下所示:
pd.concat([df1, df2], axis=1)
0     1
0  Name  Name
1  val1  val4
2  val2  val5
3  val3  val6

如果我们希望它在熊猫中看起来不错,这种格式有点磨损。

listOutput = [{0: ['Name1', 1, 2, 3, 4, 5]},
{1: ['Name2', 6, 7, 8, 9, 10]}]

如果您可以控制此列表,则可以像这样重新设置其格式:

listOutput = {'Name1': [1, 2, 3, 4, 5],
'Name2': [6, 7, 8, 9, 10]}

这导致:

>>> pd.DataFrame(listOutput)
Name1  Name2
0      1      6
1      2      7
2      3      8
3      4      9
4      5     10

如果你没有控制权,你可以这样修复它:

# This extracts the values from each dictionary in your list, and makes it
# into a properly formatted dictionary.
listOutput = {x[0]:x[1:] for x in [list(y.values())[0] for y in listOutput]}
# Produces same output as above~

另一种可能的解决方案,基于pandas.Seriespandas.concat

pd.concat(
pd.Series(listOutput)
.map(lambda x: pd.DataFrame.from_dict(x)).to_list(), axis = 1)

输出:

0     1
0  Name  Name
1     1     1
2     2     2
3     3     3
4     4     4
5     5     5

最新更新