【问题标题】:Concatenating huge dataframes with pandas用 pandas 连接巨大的数据框
【发布时间】:2020-04-30 22:41:09
【问题描述】:

我在一年的时间跨度内记录了传感器数据。数据存储在 12 个块中,有 1000 列,每列约 1000000 行。我已经制定了一个脚本来将这些块连接到一个大文件,但是在执行大约一半的时候我得到了一个MemoryError。 (我在一台有大约 70 GB 可用 RAM 的机器上运行它。)

import gc
from os import listdir
import pandas as pd

path = "/slices02/hdf/"
slices = listdir(path)
res = pd.DataFrame()

for sl in slices:
    temp = pd.read_hdf(path + f"{sl}")
    res = pd.concat([res, temp], sort=False, axis=1)
    del temp
    gc.collect()
res.fillna(method="ffill", inplace=True)
res.to_hdf(path + "sensor_data_cpl.hdf", "online", mode="w")

我也尝试过使用HDFStore,因此我不必将所有数据加载到内存中(请参阅Merging two tables with millions of rows in Python),但我无法弄清楚在我的情况下它是如何工作的。

【问题讨论】:

  • 据我所知,pandas 在处理这种大量数据方面并不是很强大 - 不是从我自己的经验或知识来看,尽管快速搜索提出了这个提示,例如 @ 987654322@
  • 我同意尤里的观点。 pandas 不适合这种数据量。您可能希望转向使用parquet 格式文件的pyspark 等解决方案。

标签: python pandas hdf5


【解决方案1】:

当您将 csv 作为 pandas DataFrame 读取时,该过程最终将占用两倍所需的内存(因为类型猜测和 pandas 试图提供的所有自动内容)。

有几种方法可以解决这个问题:

  1. 使用区块。我看到你的数据已经分块了,但可能是太大了,所以你可以使用pandas.read_hdfpandas.read_csvchunk_size参数分块读取每个文件

  2. 提供dtypes 以避免类型猜测和混合类型(例如:具有混合类型的空值字符串列),这将与low_memory 参数一起使用。

如果这还不够,您将不得不求助于分布式技术,例如 pysparkdaskmodin 甚至 pandarallel

【讨论】:

  • 我写了一个函数来转换列的dtypes。我原来的DataFramesdtypefloat64。该函数循环遍历所有列。对于每一列,它会尝试将其转换为整数格式(int8int64,具体取决于值)。如果这不起作用,dtype 将转换为 float32。这样我可以将文件块的大小减少近 60%。感谢您的提示。
【解决方案2】:

当您拥有如此多的数据时,请避免创建临时数据帧,因为它们也会占用内存。尝试一次性完成:

folder = "/slices02/hdf/"
files = [os.path.join(folder, file) for file in os.listdir(folder)]
res = pd.concat((pd.read_csv(file) for file in files), sort=False)

看看这对你有什么作用。

【讨论】:

  • 这是我一开始尝试的。它还给了我一个MemoryError。因此,我尝试逐个读取文件并在其间使用gc 清理内存。
猜你喜欢
  • 2021-07-25
  • 1970-01-01
  • 2018-05-29
  • 1970-01-01
  • 2019-03-14
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多