【发布时间】: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),我仍然看到它正在发生(并且内存很丰富)。