Pandas - 使用 read_csv 指定具有混合列数据的 dtype

Posted

技术标签:

【中文标题】Pandas - 使用 read_csv 指定具有混合列数据的 dtype【英文标题】:Pandas - Specifying dtype with mixed column data using read_csv 【发布时间】:2019-09-02 22:40:16 【问题描述】:

我正在尝试加载几个相当大的 CSV(总计:大约 30M 行/7GB)。有些列是混合的 intsfloats - 我希望这些列是 np.float16


理想情况下,read_csvdtype 参数将用于提高整个导入过程的效率。但是,这些混合数据列会引发错误。

这是代码,以及相应的错误:

def import_processing(filepath, cols, null_cols):
    result = pd.read_csv(filepath, header = None, names = cols.keys(), dtype = cols)
    result.drop(null_cols, axis = 1, inplace = True)
    return result

data_cols =  'feature_0' : np.float32,
              'feature_1' : np.float32,
              'feature_2' : np.uint32,
              'feature_3' : np.uint64,
              'feature_4' : np.uint64,
              'feature_5' : np.float16,
              'feature_6' : np.float16,
              'feature_7' : np.float16,
              'feature_8' : np.float16,
              'feature_9' : np.float16,
              'feature_10' : np.float16,
              'feature_11' : np.float16,
              'feature_12' : np.float16,
              'feature_13' : np.float16,
              'feature_14' : np.float16,
              'feature_15' : np.float16,
              'feature_16' : np.float16,
              'feature_17' : np.float16,
              'feature_18' : np.float16,
              'feature_19' : np.float16,
              'feature_20' : np.float16,
              'feature_21' : np.float16,
              'feature_22' : np.float16,
              'feature_23' : np.float16,
              'feature_24' : np.float16,
              'feature_25' : 'M8[ns]',
              'feature_26' : 'M8[ns]',
              'feature_27' : np.uint64,
              'feature_28' : np.uint32,
              'feature_29' : np.uint64,
              'feature_30' : np.uint32

files = ['./file_0.csv', './file_1.csv', './file_2.csv']
all_data = [import_processing(f, data_cols, ['feature_0', 'feature_1']) for f in files]

TypeError: Cannot cast array from dtype('O') to dtype('float16') according to the rule 'safe'

但是,如果我不使用dtype 参数,导入速度会大大减慢,因为所有混合数据类型列都导入为dtype('O') 而不是np.float16

我通过首先应用pd.to_numeric(不知道为什么这不会引发相同的错误)来解决这个问题,它将所有列转换为np.float64,然后使用astype() 转换来获取每个列到我想要的类型中(包括那些混合数据类型列到np.float16)。

这个过程非常慢,所以我想知道是否有更好的方法。目前,我的(非常慢的)工作功能如下所示:

def import_processing(filepath, cols, null_cols):
    result = pd.read_csv(filepath, header = None, names = cols.keys())
    result.drop(null_cols, axis = 1, inplace = True)

    for c in null_cols:
        cols.pop(c, None)

    result[result.columns] = result[result.columns].apply(pd.to_numeric, errors='coerce')
    result = result.astype(cols)
    return result

编辑:我读到使用 Dask(通常)是一种在 Python 中管理大型数据集的更有效的方法。我以前从未使用过它,据我所知,它基本上使用对 Pandas 的调用来处理许多操作 - 所以我想它会有相同的数据类型问题。

【问题讨论】:

这很危险,除非您使用有序字典:names = cols.keys() 另外,如果您不向我们展示cols,我们将无法帮助您。 @IanS - 我添加了更多细节。有没有更好的方法来做到这一点? 老实说,我会将所有内容读取为float64,然后转换为float16。它会避免 TypeError 吗? 【参考方案1】:

根据错误我的猜测是您的列之一不是严格的数字,并且您的数据中有一些文本,因此 Pandas 将其解释为 object-dtype 列。它无法强制此数据为 float16 类型。不过这只是猜测。

【讨论】:

以上是关于Pandas - 使用 read_csv 指定具有混合列数据的 dtype的主要内容,如果未能解决你的问题,请参考以下文章

Python Pandas——Read_csv详解

为 pandas.read_csv 指定正确的 dtypes 以获取日期时间和布尔值

pandas使用read_csv读取数据使用skiprows参数跳过指定的数据行但保留表头pandas使用to_csv函数将dataframe保存为gzip压缩文件

pandas使用read_csv函数读取csv数据设置parse_dates参数将csv数据中的指定字段数据列解析为时间日期对象

pandas使用read_csv函数读取csv数据sort_index函数基于多层列索引对数据排序(设置axis参数指定使用列索引对数据排序)

pandas使用read_csv函数读取csv数据sort_index函数基于多层列索引对数据排序(设置axis参数指定使用列索引对数据排序)