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

标签 python pandas csv dask

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

csv sample

我尝试手动显式指定 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/

相关文章:

python - 石头剪刀布游戏,无限循环

python - Pandas 交叉制表和计数

php - CSV导入功能在插入mysql数据库时添加前面的双引号

python - 如何根据分隔符将 csv 的一个单元格拆分为数据框的列

python - 使用 python 将 .csv 文件复制到 .xlsx 工作簿中

python - 在 django View 中使用 subprocess.Popen() 执行 python 脚本

python - 如何在 Flask 中捕获和读取传入 HTTP 请求的 header ?

python - 如何沿某个维度将元素添加到 PyTorch 张量?

python - 将 pandas 数据帧的一行转换为多行

Python pandas - 合并数据帧行