pandasread_csv low_memory和dtype选项

打电话时

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

我得到:

/Users/josh/anaconda/envs/py27/lib/python2.7/site-packages/pandas/io/parsers.py:1130:DtypeWarning:列(4,5,7,16)有混合types。 在导入时指定dtype选项或设置low_memory = False。

为什么low_memory选项与low_memory有关,为什么会使这个问题low_memory呢?

弃用的low_memory选项

low_memory选项没有被适当的弃用,但应该是,因为它实际上并没有做任何不同的事情[ source ]

你得到这个low_memory警告的原因是因为猜测每列的types是非常需要内存的。 pandas试图通过分析每列中的数据来确定要设置的dtype。

Dtype猜测(非常糟糕)

只有在整个文件被读取的时候,pandas才能确定列应该有哪些dtype。 这意味着在读取整个文件之前,没有任何东西可以被真正parsing,除非您在读取最后一个值时不得不更改该列的dtype。

考虑一个名为user_id的文件的例子。 它包含1000万行,user_id始终是数字。 由于pandas不知道它只是数字,它可能会保留它作为原始string,直到它读取整个文件。

指定dtypes(应始终完成)

join

 dtype={'user_id': int} 

pd.read_csv()调用会让pandas知道什么时候开始读取文件,这只是整数。

另外值得注意的是,如果文件的最后一行在user_id列中写有"foobar" ,那么如果指定了上面的dtype,则加载将会崩溃。

当定义了dtypes时破坏的数据的例子

 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: invalid literal for long() with base 10: 'foobar' 

dtypes通常是一个numpy的东西,在这里阅读更多关于他们: http ://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html

陷阱,注意事项,笔记

设置dtype=object将会使上面的警告dtype=object ,但不会使内存更有效率,只有在任何情况下才会有效。

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

转换器的使用

@sparrow正确地指出转换器的使用,以避免在指定为int的列中遇到'foobar'时大pandas爆炸。 我想补充说的是,转换器在pandas中的使用是非常繁重和低效的,应该作为最后的手段使用。 这是因为read_csv进程是一个进程。

CSV文件可以逐行处理,因此可以通过简单地将文件分割成多个部分并运行多个进程,这些大pandas不支持的东西,可以被多个并行转换器并行处理。 但这是一个不同的故事。

尝试:

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

根据pandas文件:

dtype:input栏的types名称或字典 – >types

至于low_memory, 默认情况下为True ,尚未logging。 我不认为它有关。 错误信息是通用的,所以你不应该用low_memory搞乱。 希望这有帮助,并让我知道如果你有进一步的问题

 df = pd.read_csv('somefile.csv', low_memory=False) 

这应该解决这个问题。 从CSV读取180万行时,我得到了完全相同的错误。

正如前面提到的firelynx,如果明确指定了dtype,并且混合的数据与该dtype不兼容,则加载将会崩溃。 我使用这样的转换器作为解决方法来更改具有不兼容的数据types的值,以便仍可以加载数据。

 def conv(val): if not val: return 0 try: return np.float64(val) except: return np.float64(0) df = pd.read_csv(csv_file,converters={'COL_A':conv,'COL_B':conv})