read_csv将大型的csv文件字段加载为对象

时间:2018-12-28 20:30:07

标签: python pandas csv dask

为什么read_csv会自动将我读取的所有列转换为“对象”类型?我想读取10 Gb csv(浮点型和整数型)并将其加载到熊猫数据框中。如果我用panda或dask读取了一个较小的文件(100 MB或更小),就不会遇到这个问题(所有带数字的列都将转换为对象类型)

csv sample

我试图作为read_csv的一部分手动明确指定dtype;仍然以对象结尾(使用df.dtype读取后已验证)

import pandas as pd
file='D:/path/combine.csv'
data_type={'Lat':np.float32,'Long':np.float32,   'HorizontalAccuracy':np.int,'RSRP':np.int}
data=pd.read_csv(file, low_memory=False, dtype=data_type)
data.dtypes

试图读取文件的第一行并自动获取dtypes,然后读取具有定义的dtypes的文件:以所有对象结尾

file='D:/path/combine.csv'
col_names=pd.read_csv(file, nrows=0).columns
types_dict=data_type
types_dict.update({col:np.int64 for col in col_names if col not in types_dict})
data=pd.read_csv(file, low_memory=False, dtype=data_type)
data.dtypes

TypeError:根据规则“安全”,无法将数组从dtype('O')转换为dtype('float32') 在处理上述异常期间,发生了另一个异常: ValueError:无法将字符串转换为float:'\ x1a'

在明确指定dtype时尝试使用dask读取read_csv;关于无法将字符串转换为浮点数的错误

import dask.dataframe as dd
file='D:/path/combine.csv'
data_type={'Lat':np.float32,'Long':np.float32, 'HorizontalAccuracy':np.int,'RSRP':np.int} 
ddf=dd.read_csv(file, dtype=data_type)
ddf.compute()

TypeError:根据规则“安全”,无法将数组从dtype('O')转换为dtype('float32') ValueError:无法将字符串转换为float:“纬度”

2 个答案:

答案 0 :(得分:0)

您的代码存在一些问题,最具体地说,csv文件中的列名与您要分配的dtypes的名称不同。这将引发错误,因为它们需要完全匹配。因此,将其用作我的输入文件(我尝试尽可能地复制您的文件):

Location_Lat,Location_Long,Location_H,Location_Z,QOS_RSRP
47.46058,-123.053,6,98588,-115
47.62989,-122.81,87,98312,-114
47.54865,-122.859,9,98312,-113

我注意到您还有另外一列(Location_Z),您没有在dtypes中调用它。我设置了一个数据框,用于分配dtype,并根据上述信息使用指定的列。您可以在pd.read_csv()函数中指定所需的所有内容,如下所示:

import sys

将熊猫作为pd导入 将numpy导入为np

df = pd.read_csv('fun.csv', header=0, usecols=['Location_Lat',
                                               'Location_Long',
                                               'Location_H',
                                               'QOS_RSRP'],
                 dtype={'Location_Lat':np.float32,
                        'Location_Long':np.float32,
                        'Location_H':np.int,
                        'QOS_RSRP':np.int}, low_memory=False)
print(df)
print(df.dtypes)

需要注意的几件事。我明确指定了header=0。这将确保熊猫使用csv的第一行作为标题(因此我知道名称将被称为)。如果您希望它是另一行,只需设置header=(line you want)

第二,我告诉pandas明确使用5列中的4列,因为您没有为Location_Z列指定dtype,所以我没有包括该列,但是如果您愿意,您可以只包含在上面的usecols=参数中指定它,并在dtype=参数中指定dtype。

最后,dtype dict使用数据帧中的列名称将dtype分配给它。幸运的是,我们为列分配了header=0,因此熊猫已经“知道”了列名称。在大熊猫中,与字符串对象相比,浮点数和整数具有非常低的内存成本。 df返回所有内容的对象dtype的原因是因为标头可能会以df的row1的形式读取,在这种情况下,pandas会将整列分配为对象dtypes。上面的代码在打印到屏幕上时的结果是:

[dkennetz@hpc02  fun_temp]$ python3.5 pandas_fun.py
   Location_Lat  Location_Long  Location_H  QOS_RSRP
0     47.460579    -123.053001           6      -115
1     47.629890    -122.809998          87      -114
2     47.548649    -122.859001           9      -113
Location_Lat     float32
Location_Long    float32
Location_H         int64
QOS_RSRP           int64
dtype: object

因此我们可以看到5列中只有4列被加载到数据帧中,并且dtypes确实是赋值的float32和int64。底部的dtype: object是指数据框本身,它将始终是熊猫中的数据框对象。

我希望这可以解决您可能遇到的任何问题!

答案 1 :(得分:0)

我的超时问题和将整个大型csv读取为对象(尽管它是数字)是由于缺少指定“ header = 0”引起的。更重要的是,在read_csv中放置“ header = 0”的地方将确定它是否将正常工作。

代码错误     dd.read_csv(文件,usecols = twr_coln,dtype = data_type,标头= 0) 正确的代码     dd.read_csv(file,header = 0,usecols = twr_coln,dtype = data_type)