连接多个 Pandas 数据帧时出现内存错误

Memory Error while concatenating multiple Pandas Dataframes

我们正在尝试加载 IDS-2018 dataset,它包含 10 个 CSV 文件,总共 6.4 GB。当我们尝试在 32GB RAM 服务器中连接所有 CSV 文件时,它崩溃了(进程被终止)。

我们甚至尝试通过使用

优化pandas数据帧中的存储space

def reduce_mem_usage(df):
    numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
    start_mem = df.memory_usage().sum() / 1024**2
    for col in df.columns:
        col_type = df[col].dtypes
        if col_type in numerics:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
    end_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))
    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
    return df

但是没有用。服务器在连接每个 CSV 文件时仍然崩溃。我们使用 pd.concat 连接了每个文件。整个代码是 here。如何做到这一点,以便我们做进一步的处理??

我会尝试以下方法:

  • 通过 dtypes 参数在 read_csv 上指定列类型。
  • 未创建 10 个数据帧并依赖于 del
import numpy as np
import pandas as pd

data_files = [
    './data/CSVs/02-14-2018.csv',
    './data/CSVs/02-15-2018.csv',
    ... # a few more
]

# define dtypes
data_types = {
  "col_a": np.float64,
  ... # other types
}

df = reduce_memory_usage(
    pd.read_csv(filename[0], dtype=data_types, index_col=False)
)
for filename[1:] in data_files:
    df = pd.concat(
        [
            df,
            reduce_mem_usage(
                pd.read_csv(
                    filename,
                    dtype=data_types,
                    index_col=False,
                )
            ),
        ],
        ignore_index=True,
    )

通过这种方式,您可以确保类型推断正是您所需要的,并减少内存占用。此外,如果您的数据中有分类列,这些列通常在 CSV 文件中编码为字符串,您可以通过使用分类列数据类型大大减少内存占用。