有没有办法加快 python 中处理大型 CSV 和数据帧的速度?

ran*_*123 4 python csv dataframe pandas

我正在处理一些大小在 1Gb 到 2Gb 范围内的 CSV 文件。仅将文件加载到 pandas 数据帧中就需要 20-30 分钟,而我执行的每个操作都需要 20-30 分钟,例如按列名称过滤数据帧、打印 dataframe.head() 等。有时它也会落后于我的数据帧。当我在等待期间尝试使用另一个应用程序时。我使用的是 2019 年款 Macbook Pro,但我想其他设备也是如此。

我尝试过使用modin,但数据操作仍然很慢。

有什么办法可以让我工作更有效率吗?

预先感谢您的回复。

Mic*_*ado 12

关于缩放到大型数据集的pandas 文档有一些很棒的技巧,我将在这里总结:

  1. 加载更少的数据usecols使用或nrows 参数pd.read_csv读入列或行的子集。例如,如果您的数据有很多列,但您只需要col1col2列,请使用pd.read_csv(filepath, usecols=['col1', 'col2'])。如果您要加载带有大量额外逗号的数据集(例如,行看起来像 ),这一点尤其重要。index,col1,col2,,,,,,,,,,,在这种情况下,请使用nrows仅读入数据的子集,以确保结果仅包含您需要的列。
  2. 使用有效的数据类型。默认情况下,pandas 将所有整数数据存储为有符号 64 位整数,将浮点数存储为 64 位浮点数,将字符串存储为对象或字符串类型(取决于版本)。您可以使用诸如Series.astype或 之pd.to_numeric类的downcast
  3. 使用分块。解析大数据块可能会很慢,特别是如果您的计划是按行操作然后将其写出或将数据缩减为较小的最终形式。或者,使用该low_memory标志让 Pandas 在后端使用分块迭代器,但返回单个数据帧。
  4. 使用其他库。这里列出了几个很棒的库,但我特别要提到dask.dataframe,它专门针对您的用例,通过启用 CSV 文件的分块、多核处理来镜像pandas API并具有简单的转换方法处理数据后将数据返回到正常的 pandas 数据帧(如果需要)。

此外,我认为您应该考虑一些特定于 csv 的事情:

  1. 指定列数据类型。特别是如果分块,但即使您没有,指定列类型也可以显着减少读取时间和内存使用量,并突出显示数据中的问题区域(例如,NaN 指示器或不满足 pandas 默认值之一的标志)。使用dtypes具有单一数据类型的参数来应用于所有列或列名的字典,数据类型对指示要读入的类型。或者,您可以提供converters格式化日期、时间或其他数字数据(如果不在其中) pandas 识别的格式。
  2. 指定解析器引擎- pandas 可以用纯 python(慢)或 C(快得多)读取 csv。python引擎有更多的功能(例如,目前C引擎无法读取具有复杂多字符分隔符的文件,并且无法跳过页脚)。尝试使用该参数engine='c'来确保正在使用 C 引擎。如果您需要一种不受支持的文件类型,我会尝试首先手动修复文件(例如删除页脚),然后使用 C 引擎进行解析(如果可能)。
  3. 确保捕获数字列中的所有 NaN 和数据标志。这可能是一项艰巨的任务,在输入中指定特定的数据类型有助于捕获不良情况。使用na_valueskeep_default_nadate_parser和 的converters参数pd.read_csv。目前,解释为 NaN 的默认值列表是['', '#N/A', '#N/A N/A', '#NA', '-1.#IND', '-1.#QNAN', '-NaN', '-nan', '1.#IND', '1.#QNAN', '<NA>', 'N/A', 'NA', 'NULL', 'NaN', 'n/a', 'nan', 'null']。例如,如果您的数字列具有编码为的非数字值,notANumber那么这将被遗漏,并且会导致错误(如果您指定了 dtypes)或导致 pandas 重新启动。 -将整个列分类为对象列(对内存和速度来说超级不利!)。
  4. pd.read_csv一遍又一遍地阅读文档。read_csv 的许多参数都有重要的性能考虑。pd.read_csv经过优化以平滑可被视为 csv 的大量变化,并且更多的 magic pandas 必须准备好执行(确定类型、解释 nan、转换日期(可能)、跳过页眉/页脚、推断索引/列、处理坏行等)读取速度越慢。给它尽可能多的提示/约束,你可能会发现性能大幅提高!如果这还不够,其中许多调整也将适用于dask.dataframe API,因此这可以进一步很好地扩展。