翻译 可视化:参数low_memory and dtype options什么鬼 ? Pandas.read_csv()

Pandas read_csv low_memory and dtype options 敢问这什么鬼?


提问者:Josh,2014 Jun 16 at 19:56

当处理

df = pd.read_csv('somefile.csv')

我得到

\Users\Python\Python36\python.exe E:/Python/111.py
sys:1: DtypeWarning: Columns (3) have mixed types. Specify dtype option on import or set low_memory=False.

low_memory为毛跟dtype扯上关系了?还有就是设定False就能解决问题的原理是什么?


回答者:firelynx,Dec 1 '14 at 16:04

  • The deprecated low_memory option

low_memory选项再次没有被恰当地废掉,但是真心该废,因为实际上没起啥用(source_link)

你得到low_memory警示的原因就是pandas推测各字段dtypes(数据类型)很占内存:对字段里的每个数据都分析确定dtype。

  • 数据类型推断(极差)

只有在整个文件读取完了Pandas才能确定字段的dtype。这意味着在读取完之前,啥信息都解析不到,除非你在读完某字段最后一个值那一刻冒险更改该字段的dtype。

举个栗子看,比如有个含有user_id字段的10000万行大小的文件,通常user_id都是数字类型。因为pandas不清数它是否全是数字,在读取玩整个文件前,pandas可能会把它先当成字符串类型处理。

  • 规定数据类型(永远都该做的事儿)

pd.read_csv()里边加dtype={'user_id':int},pandas在开始读取数据时就知道了:它全是int类型数据。

不过当user_id含有字符串类型数比如“foobar”的时候,这个方法就不仅没啥用,还会把读取进程弄崩溃。就像这样:

import pandas as pd
from StringIO import StringIO

csvdata =
"""
user_id, username
1, Alice
3, Bob
foobar, Caesar
"""

sio = StringIO(csvdata)
pd.read_csv(sio, dtype={"user_id":int, "username":object})

ValueError: invalidliteral for long() with base 10:'foobar'

dtype是个典型的numpy库的事儿,具体细节看这:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html

  • 那么dtype都有哪些类型呢?

这些是numpy,也是在pandas里用的

[numpy.generic,
 [[numpy.number,
   [[numpy.integer,
     [[numpy.signedinteger,
       [numpy.int8,
        numpy.int16,
        numpy.int32,
        numpy.int64,
        numpy.int64,
        numpy.timedelta64]],
      [numpy.unsignedinteger,
       [numpy.uint8,
        numpy.uint16,
        numpy.uint32,
        numpy.uint64,
        numpy.uint64]]]],
    [numpy.inexact,
     [[numpy.floating,
       [numpy.float16, numpy.float32, numpy.float64, numpy.float128]],
      [numpy.complexfloating,
       [numpy.complex64, numpy.complex128, numpy.complex256]]]]]],
  [numpy.flexible,
   [[numpy.character, [numpy.bytes_, numpy.str_]],
    [numpy.void, [numpy.record]]]],
  numpy.bool_,
  numpy.datetime64,
  numpy.object_]]

Pandas自己又弄了2个:categoricaldatetime64[ns, tz],numpy里边不能用。

Pandas字符类型查阅链接

  • 杂项,注意,附注

设定dtype=object之后可以消除上边的Low-memory警告,但是在提高memory efficiency上没有作用,非要说有作用的话那就是对process efficiency而言。

设定dtype=unicode啥用都没有,因为对于numpy来说(pandas可以说是定制版Numpy),一个unicode被当做object对象的。

  • 关于使用转换函数

如sparrow指出的,转换函数确实可以让程序在处理如被转换为int格式字段中的“foobar”时不报错,这很对。我想补充的是,转换函数在pandas上运行起来很笨重、效率很低,不到万不得已就不用。因为read_csv是单线程的。

csv格式可以一行一行处理的,通过分割成多个部分来进行多线程处理,但是pandas不支持。这就是另个一个话题了这里不讨论。

你可能感兴趣的:(python:数据预处理)