不推荐使用的 low_memory 选项
low_memory 选项没有被正确弃用,但它应该被弃用,因为它实际上并没有做任何不同的事情[source]
您收到此low_memory 警告的原因是因为猜测每一列的 dtypes 对内存的要求很高。 Pandas 尝试通过分析每列中的数据来确定要设置的 dtype。
Dtype 猜测(非常糟糕)
Pandas 只能在读取整个文件后确定列应具有的 dtype。这意味着在读取整个文件之前无法真正解析任何内容,除非您冒着在读取最后一个值时必须更改该列的 dtype 的风险。
考虑一个文件的例子,它有一个名为 user_id 的列。
它包含 1000 万行,其中 user_id 始终是数字。
由于 pandas 无法知道它只是数字,因此它可能会将其保留为原始字符串,直到它读取整个文件为止。
指定数据类型(应该总是这样做)
添加
dtype={'user_id': int}
pd.read_csv() 调用将使 pandas 知道它何时开始读取文件,这只是整数。
另外值得注意的是,如果文件的最后一行在user_id 列中写入"foobar",如果指定了上述dtype,加载将崩溃。
在定义 dtypes 时中断数据的示例
import pandas as pd
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
csvdata = """user_id,username
1,Alice
3,Bob
foobar,Caesar"""
sio = StringIO(csvdata)
pd.read_csv(sio, dtype={"user_id": int, "username": "string"})
ValueError: invalid literal for long() with base 10: 'foobar'
dtypes 通常是一个 numpy 的东西,在这里阅读更多关于它们的信息:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html
存在哪些数据类型?
我们可以访问 numpy dtypes:float、int、bool、timedelta64[ns] 和 datetime64[ns]。请注意,numpy 日期/时间 dtypes 是不时区感知的。
Pandas 用自己的方式扩展了这组 dtype:
'datetime64[ns, <tz>]' 这是一个时区感知时间戳。
'category' 本质上是一个枚举(用整数键表示的字符串来保存
'period[]' 不要与 timedelta 混淆,这些对象实际上是锚定到特定的时间段
'Sparse', 'Sparse[int]', 'Sparse[float]' 用于稀疏数据或'其中有很多孔的数据' 而不是在数据框中保存 NaN 或 None 它省略了对象,节省空间。
'Interval' 是一个独立的主题,但它的主要用途是索引。 See more here
'Int8', 'Int16', 'Int32', 'Int64', 'UInt8', 'UInt16', 'UInt32', 'UInt64' 都是可以为空的 pandas 特定整数,与 numpy 变体不同。
'string' 是用于处理字符串数据的特定 dtype,并提供对系列上的 .str 属性的访问权限。
'boolean' 类似于 numpy 'bool',但它也支持缺失数据。
在此处阅读完整的参考资料:
Pandas dtype reference
问题、注意事项、注释
设置dtype=object 将使上述警告静音,但不会提高内存效率,如果有的话,只会提高进程效率。
设置dtype=unicode 不会做任何事情,因为对于numpy,unicode 表示为object。
转换器的使用
@sparrow 正确指出了转换器的用法,以避免在指定为 int 的列中遇到 'foobar' 时 pandas 爆炸。我想补充一点,在 pandas 中使用转换器确实很重且效率低下,应该作为最后的手段使用。这是因为 read_csv 进程是单个进程。
CSV 文件可以逐行处理,因此可以通过简单地将文件分割成段并运行多个进程来更有效地由多个转换器并行处理,这是 pandas 不支持的。但这是另一回事。