我正在处理一些大小在 1Gb 到 2Gb 范围内的 CSV 文件。仅将文件加载到 pandas 数据帧中就需要 20-30 分钟,而我执行的每个操作则需要 20-30 分钟,例如按列名称过滤数据帧,打印 dataframe.head() 等。有时,当我在等待时尝试使用另一个应用程序时,它也会滞后于我的计算机。我使用的是 2019 年款 Macbook Pro,但我想其他设备也是如此。
我尝试过使用modin,但数据操作仍然很慢。
有什么办法可以让我工作更有效率吗?
预先感谢您的回复。
pandas 文档上扩展到大型数据集 https://pandas.pydata.org/pandas-docs/stable/user_guide/scale.html有一些很棒的技巧,我将在这里总结一下:
-
加载更少的数据 https://pandas.pydata.org/pandas-docs/stable/user_guide/scale.html#load-less-data。使用以下命令读入列或行的子集
usecols
or nrows
参数为pd.read_csv https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html。例如,如果您的数据有很多列,但您只需要col1
and col2
列,使用pd.read_csv(filepath, usecols=['col1', 'col2'])
。如果您要加载带有大量额外逗号的数据集(例如,行看起来像index,col1,col2,,,,,,,,,,,
。在这种情况下,使用nrows
仅读入数据的子集,以确保结果仅包含您需要的列。
-
使用高效的数据类型 https://pandas.pydata.org/pandas-docs/stable/user_guide/scale.html#use-efficient-datatypes。默认情况下,pandas 将所有整数数据存储为有符号 64 位整数,将浮点数存储为 64 位浮点数,将字符串存储为对象或字符串类型(取决于版本)。您可以使用以下工具将它们转换为较小的数据类型Series.astype https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.astype.html or pd.to_numeric https://pandas.pydata.org/docs/reference/api/pandas.to_numeric.html与
downcast
option.
-
使用分块 https://pandas.pydata.org/pandas-docs/stable/user_guide/scale.html#use-chunking。解析大数据块可能会很慢,特别是如果您的计划是按行操作然后将其写出或将数据缩减为较小的最终形式。或者,使用
low_memory
标志让 Pandas 在后端使用分块迭代器,但返回单个数据帧。
-
使用其他库 https://pandas.pydata.org/pandas-docs/stable/user_guide/scale.html#use-other-libraries。这里列出了几个很棒的库,但我要特别指出dask.dataframe https://docs.dask.org/en/latest/dataframe.html,它专门针对您的用例,通过启用镜像的 CSV 文件的分块、多核处理熊猫 API https://docs.dask.org/en/latest/dataframe.html#dask-dataframe-copies-the-pandas-api并有简单的方法在处理数据后将数据转换回正常的 pandas 数据帧(如果需要)。
此外,我认为您应该考虑一些特定于 csv 的事情:
-
指定列数据类型 https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#specifying-column-data-types。特别是在分块的情况下,但即使您没有,指定列类型也可以显着减少读取时间和内存使用量,并突出显示数据中的问题区域(例如,NaN 指示器或不满足 pandas 默认值之一的标志)。使用
dtypes
具有单个数据类型的参数应用于所有列或列名的字典,数据类型对指示要读入的类型。或者,您可以提供converters
格式化日期、时间或其他数字数据(如果它不是 pandas 识别的格式)。
-
指定解析器引擎 https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#specifying-the-parser-engine- pandas 可以用纯 python(慢)或 C(快得多)读取 csv。 python 引擎的功能稍微多一些(例如,目前 C 引擎无法读取具有复杂的多字符分隔符的文件,并且无法跳过页脚)。尝试使用参数
engine='c'
以确保正在使用 C 引擎。如果您需要一种不受支持的文件类型,我会尝试首先手动修复文件(例如删除页脚),然后使用 C 引擎进行解析(如果可能)。
-
确保捕获数字列中的所有 NaN 和数据标志。这可能是一项艰巨的任务,在输入中指定特定的数据类型有助于捕获不良情况。使用
na_values
, keep_default_na
, date_parser
, and converters
论点pd.read_csv https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html。目前,解释为 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
那么这将被错过,并且要么导致错误(如果指定了数据类型),要么导致 pandas 将整个列重新分类为对象列(对内存和速度来说超级糟糕!)。
-
阅读pd.read_csv https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html一遍又一遍地文档。read_csv 的许多参数都有重要的性能考虑。
pd.read_csv
经过优化以平滑可被视为 csv 的大量变化,并且更多的 magic pandas 必须准备好执行(确定类型、解释 nan、转换日期(可能)、跳过页眉/页脚、推断索引/列、处理坏行等)读取速度越慢。给它尽可能多的提示/约束,你可能会发现性能大幅提高!如果这还不够,其中许多调整也将适用于dask.dataframe https://docs.dask.org/en/latest/dataframe.htmlAPI,因此可以很好地进一步扩展。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)