Pandas read_csv:low_memory 和 dtype 选项
回答问题 df = pd.read_csv('somefile.csv') ...给出一个错误: .../site-packages/pandas/io/parsers.py:1130:DtypeWarning:列(4、5、7、16)具有混合类型。在导入时指定 dtype 选项或设置 low_memoryu003dFalse。 为什么dtype选项与low_memory相关,为什么low_memo
回答问题
df = pd.read_csv('somefile.csv')
...给出一个错误:
.../site-packages/pandas/io/parsers.py:1130:DtypeWarning:列(4、5、7、16)具有混合类型。在导入时指定 dtype 选项或设置 low_memoryu003dFalse。
为什么dtype
选项与low_memory
相关,为什么low_memory=False
会有所帮助?
Answers
不推荐使用的 low_memory 选项
low_memory
选项没有被正确弃用,但它应该被弃用,因为它实际上并没有做任何不同的事情[source]
您收到此low_memory
警告的原因是因为猜测每列的 dtypes 对内存的要求很高。 Pandas 试图通过分析每列中的数据来确定要设置的 dtype。
Dtype猜测(非常糟糕)
Pandas 只能在读取整个文件后确定列应具有的 dtype。这意味着在读取整个文件之前无法真正解析任何内容,除非您冒着在读取最后一个值时必须更改该列的 dtype 的风险。
考虑一个文件的例子,它有一个名为 user_id 的列。它包含 1000 万行,其中 user_id 始终是数字。由于 pandas 无法知道它只是数字,因此它可能会将其保留为原始字符串,直到它读取整个文件。
指定 dtypes(应该总是这样做)
添加
dtype={'user_id': int}
到pd.read_csv()
调用将使熊猫知道它何时开始读取文件,这只是整数。
另外值得注意的是,如果文件的最后一行将"foobar"
写入user_id
列,则如果指定了上述 dtype,则加载将崩溃。
定义 dtype 时中断数据的示例
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
存在哪些 dtypes?
我们可以访问 numpy dtypes:float、int、bool、timedelta64[ns] 和 datetime64[ns]。请注意,numpy 日期/时间 dtypes not 时区感知。
Pandas 用自己的方式扩展了这组 dtypes:
'datetime64[ns, <tz>]'
这是一个时区感知时间戳。
'category' 本质上是一个枚举(由整数键表示的字符串以保存
'period[]' 不要与 timedelta 混淆,这些对象实际上是锚定到特定的时间段
'Sparse', 'Sparse[int]', 'Sparse[float]' 用于稀疏数据或'其中有很多孔的数据' 而不是在数据框中保存 NaN 或 None 它省略了对象,节省空间。
“间隔”是一个独立的主题,但它的主要用途是用于索引。在这里查看更多
'Int8'、'Int16'、'Int32'、'Int64'、'UInt8'、'UInt16'、'UInt32'、'UInt64' 都是可以为空的 pandas 特定整数,与 numpy 变体不同。
'string' 是用于处理字符串数据的特定 dtype,并允许访问系列上的.str
属性。
'boolean' 类似于 numpy 'bool' 但它也支持缺失数据。
在此处阅读完整的参考资料:
Pandas dtype 参考
陷阱、注意事项、注释
设置dtype=object
将使上述警告静音,但不会提高内存效率,如果有的话,只会提高进程效率。
设置dtype=unicode
不会做任何事情,因为对于 numpy,unicode
表示为object
。
转换器的使用
@sparrow 正确指出了转换器的使用,以避免熊猫在指定为int
的列中遇到'foobar'
时爆炸。我想补充一点,在 pandas 中使用转换器确实很重且效率低下,应该作为最后的手段使用。这是因为 read_csv 进程是单个进程。
CSV 文件可以逐行处理,因此可以通过简单地将文件切割成段并运行多个进程来更有效地由多个转换器并行处理,这是 pandas 不支持的。但这是一个不同的故事。
更多推荐
所有评论(0)