我想根据已经提供的大多数潜在解决方案做出更全面的回答。我还想指出另一种可能有助于阅读过程的潜在帮助。
选项 1:数据类型
"dtypes" 是一个非常强大的参数,您可以使用它来减少read 方法的内存压力。请参阅this 和this 答案。 Pandas 默认尝试推断数据的 dtypes。
参考数据结构,每存储一个数据,就会发生一次内存分配。基本参考以下值(下表说明了 C 编程语言的值):
The maximum value of UNSIGNED CHAR = 255
The minimum value of SHORT INT = -32768
The maximum value of SHORT INT = 32767
The minimum value of INT = -2147483648
The maximum value of INT = 2147483647
The minimum value of CHAR = -128
The maximum value of CHAR = 127
The minimum value of LONG = -9223372036854775808
The maximum value of LONG = 9223372036854775807
参考this页面查看NumPy和C类型的匹配。
假设您有一个由数字组成的整数数组。您可以在理论上和实际上分配,例如 16 位整数类型的数组,但是您将分配比实际需要存储该数组更多的内存。为了防止这种情况,您可以在read_csv 上设置dtype 选项。您不想将数组项存储为长整数,实际上您可以使用 8 位整数(np.int8 或 np.uint8)来适应它们。
观察以下 dtype 映射。
来源:https://pbpython.com/pandas_dtypes.html
您可以将dtype 参数作为pandas 方法的参数作为read 上的dict 传递,例如{column: type}。
import numpy as np
import pandas as pd
df_dtype = {
"column_1": int,
"column_2": str,
"column_3": np.int16,
"column_4": np.uint8,
...
"column_n": np.float32
}
df = pd.read_csv('path/to/file', dtype=df_dtype)
选项 2:按块读取
分块读取数据允许您访问内存中的部分数据,并且您可以对数据进行预处理并保留处理后的数据而不是原始数据。如果将此选项与第一个选项 dtypes 结合使用会更好。
我想指出该过程的 pandas 食谱部分,您可以在其中找到它 here。注意那里的那两个部分;
选项 3:Dask
Dask 是一个框架,在Dask's website 中定义为:
Dask 为分析提供高级并行性,为您喜爱的工具提供大规模性能
它的诞生是为了覆盖熊猫无法到达的必要部分。 Dask 是一个强大的框架,通过以分布式方式处理数据,您可以访问更多数据。
您可以使用 dask 对整个数据进行预处理,Dask 负责分块部分,因此与 pandas 不同的是,您只需定义处理步骤并让 Dask 完成工作。 Dask 在compute 和/或persist 明确推送之前不会应用计算(请参阅答案here 了解差异)。
其他辅助(想法)
- 为数据设计的 ETL 流。只保留原始数据中需要的内容。
- 首先,使用 Dask 或 PySpark 等框架将 ETL 应用于整个数据,然后导出处理后的数据。
- 然后看看处理后的数据是否可以作为一个整体放入内存中。
- 考虑增加 RAM。
- 考虑在云平台上使用该数据。