Fei*_*Liu 5 python dataframe pandas
我发现如果我们从 DataFrame 列表中初始化 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)
Run Code Online (Sandbox Code Playgroud)
最初我认为 Series 初始化意外地深度复制了 DataFrame,这使得它变慢,但事实证明它只是像=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]
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
实际使用情况:我有一个表加载器,它读取磁盘上的内容并返回 pandas DataFrame (表)。为了加快阅读速度,我使用并行工具(来自此答案)执行多次读取(例如,每次读取针对一个日期),并且它返回一个(表)列表。现在我想将此列表转换为具有适当索引(例如读取中使用的日期或文件位置)的 pandas Series 对象,但 Series 构造花费了荒谬的时间(如上面所示的示例代码)。我当然可以将其编写为 for 循环来解决问题,但这会很难看。此外,我想知道真正花时间在这里的是什么。有什么见解吗?
这不是对OP问题的直接回答(从数据帧列表构建一系列数据时导致速度变慢的原因):
我可能会错过用于pd.Series存储数据帧列表的一个重要优势,但是如果这对于下游流程并不重要,那么更好的选择可能是将其存储为数据帧字典或连接到单个数据帧中。
对于数据帧字典,可以使用如下内容:
d = {n: df for n, df in enumerate(l)}
# can change the key to something more useful in downstream processes
Run Code Online (Sandbox Code Playgroud)
对于串联:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
410 次 |
| 最近记录: |