已弃用的 low_memory 选项
The low_memory
选项没有被正确弃用,但它应该被弃用,因为它实际上并没有做任何不同的事情[source https://github.com/pydata/pandas/issues/5888]
你得到这个的原因low_memory
警告是因为猜测每列的数据类型非常需要内存。 Pandas 尝试通过分析每列中的数据来确定要设置的数据类型。
Dtype 猜测(非常糟糕)
Pandas 仅在读取整个文件后才能确定列应具有的数据类型。这意味着在读取整个文件之前无法真正解析任何内容,除非您在读取最后一个值时冒着必须更改该列的 dtype 的风险。
考虑一个文件的示例,该文件具有名为 user_id 的列。
它包含 1000 万行,其中 user_id 始终为数字。
由于 pandas 无法知道它只是数字,因此它可能会将其保留为原始字符串,直到读取整个文件。
指定数据类型(应该始终这样做)
adding
dtype={'user_id': int}
to the pd.read_csv() http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html调用将使 pandas 知道它何时开始读取文件,这只是整数。
另外值得注意的是,如果文件中的最后一行有"foobar"
写在user_id
列,如果指定了上述数据类型,加载将会崩溃。
定义数据类型时损坏的数据示例
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'
数据类型通常是一个令人费解的东西,请在此处阅读有关它们的更多信息:http://docs.scipy.org/doc/numpy/reference/ generated/numpy.dtype.html http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html
存在哪些数据类型?
我们可以访问 numpy 数据类型:float、int、bool、timedelta64[ns] 和 datetime64[ns]。请注意,numpy 日期/时间 dtypes 是not时区意识。
Pandas 用自己的数据类型扩展了这组数据类型:
'datetime64[ns, <tz>]'
这是一个时区感知时间戳。
'category' 本质上是一个枚举(由整数键表示的字符串以保存
'period[]' 不要与 timedelta 混淆,这些对象实际上锚定到特定的时间段
'Sparse'、'Sparse[int]'、'Sparse[float]' 用于稀疏数据或“其中有很多空洞的数据”,它不是在数据框中保存 NaN 或 None,而是省略对象,从而节省空间。
“间隔”是它自己的一个主题,但它的主要用途是用于索引。在这里查看更多内容 https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html#advanced-intervalindex
'Int8'、'Int16'、'Int32'、'Int64'、'UInt8'、'UInt16'、'UInt32'、'UInt64' 都是 pandas 特定的可为空的整数,与 numpy 变体不同。
'string' 是一种用于处理字符串数据的特定数据类型,并提供对.str
系列上的属性。
“boolean”类似于 numpy 的“bool”,但它也支持缺失数据。
在这里阅读完整的参考:
Pandas 数据类型参考 https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dtypes.html
陷阱、警告、注释
Setting dtype=object
将使上述警告静音,但不会提高内存效率,只会提高处理效率(如果有的话)。
Setting dtype=unicode
不会做任何事情,因为对于 numpy,aunicode
表示为object
.
转换器的使用
@sparrow正确地指出了转换器的用法,以避免熊猫遇到时爆炸'foobar'
在指定为的列中int
。我想补充一点,在 pandas 中使用转换器确实很重且效率低下,应该作为最后的手段使用。这是因为 read_csv 进程是单个进程。
CSV 文件可以逐行处理,因此可以通过简单地将文件切成段并运行多个进程来更有效地由多个转换器并行处理,这是 pandas 不支持的。但这是一个不同的故事。