【问题标题】:Slow Pandas Series initialization from list of DataFrames数据帧列表中的慢熊猫系列初始化
【发布时间】:2021-12-30 03:35:00
【问题描述】:

我发现如果我们从 DataFrames 列表中初始化 pandas Series 对象会非常慢。例如。以下代码:

import pandas as pd
import numpy as np

# creating a large (~8GB) list of DataFrames.
l = [pd.DataFrame(np.zeros((1000, 1000))) for i in range(1000)]

# This line executes extremely slow and takes almost extra ~10GB memory. Why?
# It is even much, much slower than the original list `l` construction.
s = pd.Series(l)

最初我认为 Series 初始化不小心深度复制了 DataFrames,这使它变慢,但结果证明它只是像 python 中通常的 = 那样通过引用复制。

另一方面,如果我只是创建一个系列并手动浅复制元素(在 for 循环中),它会很快:

# This for loop is faster. Why?
s1 = pd.Series(data=None, index=range(1000), dtype=object)
for i in range(1000):
    s1[i] = l[i]

这里发生了什么?

实际使用:我有一个表加载器,它读取磁盘上的内容并返回一个 pandas DataFrame(一个表)。为了加快阅读速度,我使用了一个并行工具(来自this answer)来执行多次读取(例如,每次读取都针对一个日期),并返回一个(表)列表。现在我想将此列表转换为具有适当索引的 pandas Series 对象(例如,读取中使用的日期或文件位置),但是 Series 构造需要大量时间(如上面显示的示例代码)。我当然可以把它写成一个 for 循环来解决这个问题,但这会很丑陋。此外,我想知道这里真正花时间的是什么。有什么见解吗?

【问题讨论】:

  • 我无法重现 pd.Series(l) 花费的时间太长(由于 RAM 有限,在 Google Colab 上使用 i in range(600))。也许您的机器开始使用交换内存?
  • @hilberts_drinking_problem:确实很奇怪。我也在 Google Colab 上尝试过,它与您发现的一致:pd.Series(l) 似乎没有问题。我还怀疑它与 pandas 版本有关(我的是 1.3.5,而我尝试的 Google Colab 运行时使用的是 1.1.5)。但是,在我切换到 1.1.5(Google Colab 使用的那个)之后,问题仍然存在(在我的 mac book pro 上)。这很奇怪。此外,我认为这与交换内存无关:即使我在我的 Mac 上将其缩小到 i in range(500),我仍然看到它正在发生(并且内存很丰富)。

标签: python pandas dataframe


【解决方案1】:

这不是对 OP 问题的直接回答(从数据帧列表构建系列时导致速度变慢的原因):

我可能错过了使用pd.Series 存储数据帧列表的一个重要优势,但是如果这对下游流程并不重要,那么更好的选择可能是将其存储为数据帧字典或连接到单个数据框。

对于数据帧的字典,可以使用如下内容:

d = {n: df for n, df in enumerate(l)}
# can change the key to something more useful in downstream processes

对于连接:

w = pd.concat(l, axis=1)
# note that when using with the snippet in this question
# the column names will be duplicated (because they have
# the same names) but if your actual list of dataframes
# contains unique column names, then the concatenated
# dataframe will act as a normal dataframe with unique
# column names

【讨论】:

    猜你喜欢
    • 2016-09-21
    • 1970-01-01
    • 2017-03-10
    • 2022-12-10
    • 2019-10-12
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多