首页 文章

Pandas read_csv low_memory和dtype选项

提问于
浏览
196

打电话的时候

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)有混合类型 . 在导入时指定dtype选项或设置low_memory = False .

为什么 dtype 选项与 low_memory 相关,为什么要使它 False 帮助解决这个问题?

5 回答

  • 275

    已弃用的low_memory选项

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

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

    Dtype猜测(非常糟糕)

    Pandas只能确定读取整个文件后列应该具有什么类型 . 这意味着在读取整个文件之前无法真正解析任何内容,除非您在读取最后一个值时可能需要更改该列的dtype .

    考虑一个文件的示例,该文件具有名为user_id的列 . 它包含1000万行,其中user_id始终为数字 . 由于大熊猫不知道它只是数字,它可能会将它保留为原始字符串,直到它读取整个文件 .

    指定dtypes(应始终完成)

    加入

    dtype={'user_id': int}
    

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

    另外值得注意的是,如果文件中的最后一行在 user_id 列中写入 "foobar" ,如果指定了上述dtype,则加载会崩溃 .

    定义dtypes时中断的数据示例

    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": object})
    
    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

    [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_]]
    

    熊猫还添加了两个dtypes: categoricaldatetime64[ns, tz] 在numpy中不可用

    Pandas dtype reference

    陷阱,警告,笔记

    设置 dtype=object 将使上述警告静音,但不会使其更高效,只有处理有效 .

    设置 dtype=unicode 将不会执行任何操作,因为numpy, unicode 表示为 object .

    转换器的使用

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

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

  • 26

    尝试:

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

    根据熊猫文档:

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

    至于low_memory,它是真的by default并且不认为它的相关性 . 错误消息是通用的,所以无论如何你都不需要搞乱low_memory . 希望这有帮助,如果您有其他问题,请告诉我

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

    这应该可以解决问题 . 当从CSV读取1.8M行时,我得到了完全相同的错误 .

  • 0

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

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

    我有一个约400MB文件的类似问题 . 设置 low_memory=False 为我做了伎俩 . 首先做简单的事情,我会检查你的数据帧是否仍然存在错误,值得确保你的 .csv 文件没问题,快速查看Excel并确保没有明显的损坏 . 破碎的原始数据可能会造成严重破坏......

相关问题