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_memory=False。

为什么 dtype 选项与 low_memory 相关,为什么 low_memory=False 帮助?

原文由 Josh 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

已弃用的 low_memory 选项

low_memory 选项没有被正确弃用,但它应该被弃用,因为它实际上并没有做任何不同的事情[ 来源]

你得到这个 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 知道时区。

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’ 但它也支持缺失数据。

在此处阅读完整的参考资料:

熊猫 dtype 参考

陷阱、注意事项、注释

设置 dtype=object 将使上述警告静音,但不会提高内存效率,如果有的话,只会提高进程效率。

设置 dtype=unicode 不会做任何事情,因为对于 numpy,一个 unicode 表示为 object

转换器的使用

@sparrow 正确指出了转换器的使用,以避免熊猫在指定为 int 的列中遇到 'foobar' 时爆炸。我想补充一点,在 pandas 中使用转换器确实很重且效率低下,应该作为最后的手段使用。这是因为 read_csv 进程是单个进程。

CSV 文件可以逐行处理,因此可以通过简单地将文件分成段并运行多个进程来更有效地由多个转换器并行处理,这是 pandas 不支持的。但这是一个不同的故事。

原文由 firelynx 发布,翻译遵循 CC BY-SA 4.0 许可协议

尝试:

 dashboard_df = pd.read_csv(p_file, sep=',', error_bad_lines=False, index_col=False, dtype='unicode')

根据熊猫文档:

dtype : 列的类型名称或字典 -> 类型

至于 low_memory,它 默认 为 True 并且尚未记录。我认为它不相关。错误消息是通用的,因此您无论如何都不需要弄乱 low_memory 。希望这对您有所帮助,如果您还有其他问题,请告诉我

原文由 hd1 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题