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})