将具有相同索引的熊猫系列列表转换为字典

Posted

技术标签:

【中文标题】将具有相同索引的熊猫系列列表转换为字典【英文标题】:Convert a list of pandas series with the same index into a dictionary 【发布时间】:2019-09-26 20:22:53 【问题描述】:

我有一个熊猫系列列表,每个系列都有相同的索引。我想将此列表转换为字典,其中键是索引值(所有系列都相同,值是系列对象中的值列表)。这是一个例子:

series_1:
A 1
B 2
C 3

series_2:
A 11
B 22
C 33

[series_1, series_2] 转换为'A': [1,11], 'B': [2,22], 'C': [3,33] 的最有效(理想情况下没有循环)方法是什么?我需要一种有效的方法,因为我拥有的系列数量是 10K,每个系列有 20K 个元素。

【问题讨论】:

【参考方案1】:

最好的性能是转换为numpy数组字典而不是列表字典,并使用系列的np.array构造字典。

此外,如果您真的需要列表字典,在s.indexnp.array.tolist() 上使用dictzip 仍然比上述两种方法好得多。上述两种方法都有创建数据帧的开销。

设置一系列 20k 数字

s = pd.Series(np.arange(20000))

在 1000 系列上创建 np.array 的字典

dict(zip(s.index, np.column_stack([s.values]*1000)))

在 1000 系列上创建 list 的字典

dict(zip(s.index, np.column_stack([s.values]*1000).tolist()))

计时所有 4 种方法:

In [1071]: %timeit dict(zip(s.index, np.column_stack([s.values]*1000)))
195 ms ± 879 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [1072]:  %timeit dict(zip(s.index, np.column_stack([s.values]*1000).tolist()))
1.05 s ± 4.26 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [1075]: %timeit pd.concat([s]*1000).groupby(level=0).apply(list).to_dict()
7.01 s ± 70.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [1077]: %timeit pd.concat([s]*1000, axis=1).T.to_dict('l')
2.83 s ± 11.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

使用带有dictzip 的系列数组numpy 比使用pd.concat 的两种方法快得多。 np.array 的字典在 195 ms 处最快,比下一个快 5 倍以上。

【讨论】:

【参考方案2】:

这是一种方法concat 然后groupby

pd.concat([s1,s2]).groupby(level=0).apply(list).to_dict()
Out[375]: 'A': [1, 11], 'B': [2, 22], 'C': [3, 33]

更新

pd.concat([s1,s2],axis=1).T.to_dict('l')
Out[379]: 'A': [1, 11], 'B': [2, 22], 'C': [3, 33]

【讨论】:

谢谢。请查看我在问题中的编辑,了解我需要效率的原因。对于每个具有 20K 元素的 1000 个系列,您的方法需要 8 秒,而列表和索引上的嵌套循环需要 5 秒。我需要一种更有效的方法。 相同设置的更新版本需要 2.5 秒,谢谢。

以上是关于将具有相同索引的熊猫系列列表转换为字典的主要内容,如果未能解决你的问题,请参考以下文章

将带有列表的字典转换为熊猫数据框

将熊猫数据框转换为具有多个键的字典

如何将包含元组列表的字典中的字典转换为熊猫数据框

将包含熊猫系列的列转换为特征[重复]

在熊猫列表中提取列表

将 Python 列表转换为熊猫系列