【发布时间】:2023-03-25 01:06:02
【问题描述】:
这个问题更具概念性/理论性(与非常大的数据集的运行时间有关),因此我很抱歉没有展示一个最小的示例。
我有一堆来自两个不同传感器的数据帧,我需要最终将它们连接成来自两个不同传感器(df_snsr1 和df_snsr2)的两个非常大数据帧,然后左连接到单个数据帧。我的数据是这样的,我也可以先加入,然后再连接,或某种组合。我正在尝试找出最有效的方法。
通过阅读this SO answer,我知道pandas.concat 为其所有数据帧的连接分配空间,如果您在循环中执行此操作,可能会导致O(N**2) 复制和一些主要的减速。因此,我目前首先构建一个大数据帧列表(从文件加载),一次将它们连接起来,然后加入两个大数据帧:
df_list = []
for file in my_pickle_files_snsr1: # O(M) loop over M files
df_list.append(pd.read_pickle(file)) # O(1) append, M times
df_snsr1 = pd.concat(df_list) # O(N) copies of N records
# repeat for sensor 2 (df_snsr2)
df_snsr1.join(df_snsr2, on=['some', 'columns']) # O(dunno, maybe bears?)
我在pandas.DataFrame.join 的文档中找不到任何有关执行速度的信息。是O(N)吗? O(N**2)?我的想法是,如果它与pandas.concat 的顺序相似,那么我执行这两个操作的顺序实际上并不重要。但是,如果是O(N**2),那么我加入可能会更有效率许多小的数据帧,然后将它们连接起来,而不是连接然后加入。整个操作需要足够长的时间,值得我在这里提出问题,所以“运行它并查看”是行不通的。
有人知道join 使用的是什么算法以及它的执行大O 顺序是什么吗?或者有人对获得join 和concat 的最有效组合有任何其他建议吗?
【问题讨论】:
-
虽然我也对您的问题的答案感兴趣,但我建议您查看 dask 提供的solution 正是针对此问题(即,将大量文件读入一个 DataFrame)。它并不真正支持读取大量 pickle 文件,但 csv、parquet、hdf 和许多其他文件类型真的很容易以这种方式读取。
import dask.dataframe as dd; df_snsr1 = dd.read_csv(list_of_csv_files_or_path_regex); df_snsr1 = df_snsr1.compute()
标签: python pandas dataframe big-o execution-time