为什么 read_csv 会自动将我读取的所有列转换为“对象”类型?我想读取 10 Gb csv(浮点型和整数型)并将其加载到 pandas 数据框中。如果我使用 panda 或 dask 读取较小的文件(100 MB 或更少),我不会遇到此问题(其中所有带有数字的列都转换为对象类型)
我尝试手动显式指定 dtype 作为 read_csv 的一部分;仍然最终得到对象(用 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
尝试读取文件的第一行并自动获取数据类型,然后读取具有定义的数据类型的文件:最终得到所有对象
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
类型错误:无法根据规则“安全”将数组从 dtype('O') 转换为 dtype('float32') 在处理上述异常的过程中,又出现了一个异常: ValueError:无法将字符串转换为 float :'\x1a'
在显式指定 dtype 的同时尝试使用 dask 进行 read_csv ;收到有关无法将字符串转换为 float 的错误
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()
类型错误:无法根据规则“安全”将数组从 dtype('O') 转换为 dtype('float32') ValueError:无法将字符串转换为 float :'Latitude'
最佳答案
您的代码存在一些问题,最具体地说,您的 csv 文件中的列名称与您分配的数据类型的名称不同。这会引发错误,因为它们需要完全匹配。因此,使用它作为我的输入文件(我尝试尽可能多地复制您的文件):
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),您没有在数据类型中调用它。我设置了一个数据框来分配数据类型,并根据您上面的信息使用指定的列。您可以在 pd.read_csv()
中指定您想要的所有内容。功能如下:
import sys
将 pandas 导入为 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
。这将确保 pandas 使用 csv 的第一行作为标题(这样我就知道这些名称将被称为什么)。如果您希望它成为不同的行,只需设置 header=(line you want)
其次,我告诉 pandas 仅显式使用 5 列中的 4 列,因为您没有为 Location_Z
指定 dtype列,我没有包含该列,但如果您需要它,可以将其包含在 usecols=
中上面的参数并在 dtype=
中指定 dtype参数。
最后,dtype 字典使用数据帧中的列名称来分配 dtype。幸运的是,我们为列分配了 header=0
所以 pandas 已经“知道”列名了。在 pandas 中,与字符串对象相比, float 和整数的内存成本非常低。您的 df 为所有内容返回对象 dtypes 的原因是因为标题可能会作为 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 列被加载到数据帧中,并且数据类型确实是指定的 float32 和 int64。 dtype: object
底部指的是数据框本身,它始终是 pandas 中的数据框对象。
我希望这能解决您可能遇到的任何问题!
关于python - read_csv 将大型 csv 文件字段加载为对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53963972/