读取数据集
创建数据集
- 创建一个人工数据集,并存储在CSV(逗号分隔值)文件
../data/house_tiny.csv
中
..
表示当前文件所在目录的上一级目录
- (因为我现在打开的jupyter notebook在
../chapter_prelliminaries
目录下,所以他会在../data
目录创建一个data
数据集)
1 2 3 4 5 6 7 8 9 10
| import os
os.makedirs(os.path.join('..', 'data'), exist_ok=True) data_file = os.path.join('..', 'data', 'house_tiny.csv') with open(data_file, 'w') as f: f.write('NumRooms,Alley,Price\n') f.write('NA,Pave,127500\n') f.write('2,NA,106000\n') f.write('4,NA,178100\n') f.write('NA,NA,140000\n')
|
加载数据集
从创建的CSV文件中加载原始数据,,我们导入pandas
包并调用read_csv
函数
1 2 3 4 5 6 7 8 9
| (tensor([[3., 1., 0., 0., 0.], [4., 0., 0., 1., 0.], [3., 0., 1., 0., 0.]], dtype=torch.float64), tensor([127500, 178100, 140000]))
import pandas as pd
data = pd.read_csv(data_file, na_values="NA") print(data)
|
加载读取的data
:
1 2 3 4 5
| NumRooms Alley Price 0 NaN Pave 127500 1 2.0 NaN 106000 2 4.0 NaN 178100 3 NaN NaN 140000
|
处理缺失值
方法
- 插值法:用一个替代值弥补缺失值
- 删除法:忽略缺失值
插值法
通过位置索引iloc
,我们将data
分成inputs
和outputs
, 其中前者为data
的前两列,而后者为data
的最后一列
1
| inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| // inputs的值 NumRooms Alley 0 NaN Pave 1 2.0 NaN 2 4.0 NaN 3 NaN NaN
// inputs的类型 NumRooms float64 Alley object dtype: object
// outputs的值 NumRooms Alley_Pave Alley_nan 0 3.0 1.0 0.0 1 2.0 0.0 1.0 2 4.0 0.0 1.0 3 3.0 0.0 1.0 0 127500 1 106000 2 178100 3 140000 Name: Price, dtype: int64
// outputs的类型 int64
|
对于inputs
中缺少的数值,我们用同一列的均值替换“NaN”项
1 2
| inputs['NumRooms'] = inputs['NumRooms'].fillna(inputs['NumRooms'].mean()) print(inputs)
|
1 2 3 4 5
| NumRooms Alley 0 3.0 Pave 1 2.0 NaN 2 4.0 NaN 3 3.0 NaN
|
[对于inputs
中的类别值或离散值,我们将“NaN”视为一个类别。] 由于“巷子类型”(“Alley”)列只接受两种类型的类别值“Pave”和“NaN”, pandas
可以自动将此列转换为两列“Alley_Pave”和“Alley_nan”。 类型为“Pave”的行会将“Alley_Pave”的值设置为1,“Alley_nan”的值设置为0。 缺少类型的行会将“Alley_Pave”和“Alley_nan”分别设置为0和1。
1 2
| inputs = pd.get_dummies(inputs, dummy_na=True) print(inputs)
|
1 2 3 4 5
| NumRooms Alley_Pave Alley_nan 0 3.0 True False 1 2.0 False True 2 4.0 False True 3 3.0 False True
|
转换为张量格式
注意:
如果这一部报错,有可能是inputs.values
无法把布尔值直接当作浮点数处理(大多数机器学习的情况下是可以直接转化的),你需要先把inputs中的布尔值转化为浮点数:
1 2
| inputs = inputs.astype(float) print(inputs)
|
1 2 3 4 5
| NumRooms Alley_Pave Alley_nan 0 3.0 1.0 0.0 1 2.0 0.0 1.0 2 4.0 0.0 1.0 3 3.0 0.0 1.0
|
其他方法
删除法
读取数据集
1 2 3 4 5 6 7 8 9 10
| import os
os.makedirs(os.path.join('..', 'data'), exist_ok=True) data_file = os.path.join('..', 'data', 'house_tiny2.csv') with open(data_file, 'w') as f: f.write('NumRooms,Alley,Price\n') f.write('3,Pave,127500\n') f.write('2,NA,106000\n') f.write('4,wood,178100\n') f.write('3,granite,140000\n')
|
加载数据集:
1 2 3 4
| import pandas as pd
data = pd.read_csv(data_file) print(data)
|
1 2 3 4 5
| NumRooms Alley Price 0 3 Pave 127500 1 2 NaN 106000 2 4 wood 178100 3 3 granite 140000
|
删除数据
- 用
pandas
的 dropna()
方法来删除包含 NA
或缺失值的行
1 2
| data = data.dropna() print(data)
|
1 2 3 4
| // NumRooms Alley Price 0 3 Pave 127500 2 4 wood 178100 3 3 granite 140000
|
独热编码
1 2 3
| inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2] print(inputs) print(outputs)
|
1 2 3 4 5 6 7 8
| // NumRooms Alley 0 3 Pave 2 4 wood 3 3 granite 0 127500 2 178100 3 140000 Name: Price, dtype: int64
|
1 2
| inputs = pd.get_dummies(inputs, dummy_na=True) print(inputs)
|
1 2 3 4
| // NumRooms Alley_Pave Alley_granite Alley_wood Alley_nan 0 3 True False False False 2 4 False False True False 3 3 False True False False
|
转换为张量格式
1 2 3 4
| inputs = inputs.astype(float) import torch X, y = torch.tensor(inputs.values), torch.tensor(outputs.values) X, y
|
1 2 3 4
| // (tensor([[3., 1., 0., 0., 0.], [4., 0., 0., 1., 0.], [3., 0., 1., 0., 0.]], dtype=torch.float64), tensor([127500, 178100, 140000]))
|
torch
torch.arange()
1
| torch.arange(start=0, end, step=1, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
|
start
:起始值(默认0)
end
:结束值
step
:相邻点之间的间隙
dtype
:返回的tensor所需数据类型
requires_grad
:指定返回tensor需不需要梯度(默认False)
os
os.makedirs()
os.makedirs()
方法用于递归创建多层目录。
如果子目录创建失败或者已经存在,会抛出一个 OSError 的异常
如果第一个参数 path 只有一级,即只创建一层目录,则与 mkdir() 函数相同。
1
| os.makedirs(path, mode=511, exist_ok=False)
|
path
:需要递归创建的目录,可以是相对或者绝对路径(在path上直接写要创建的文件名)
exist_ok
:是否在目录存在时触发异常
False
:(默认值),则在目标目录已存在的情况下触发 FileExistsError 异常
True
:在目标目录已存在的情况下不会触发 FileExistsError 异常
os.path.join()
连接两个或更多的路径名组件
1
| os.path.join(path, *paths)
|
- 如果有一个组件是一个绝对路径,则在它之前的所有组件均会被舍弃
- 如果各组件名首字母不包含
\
,则函数会自动加上
- 如果最后一个组件为空,则生成的路径以一个
\
分隔符结尾
with open()
用来打开本地文件,他会在使用完毕后,自动关闭文件,相对open()
省去了写close()
的麻烦
1 2 3
| with open(file="file_path",mode="r/w/a",encoding="utf-8") as f: data=f.read/write() print(data)
|
- mode:
r
:只读(默认)
w
:只写(会清除之前写的内容)
a
:追加内容(会在已经写的内容基础上追加新的内容)
- encoding:系统默认(不用管)
write()
write()
方法用于向文件中写入指定字符串
1
| fileObject.write( [ str ])
|
CSV
逗号分隔值(Comma-Separated Values,CSV),其文件以纯文本形式存储表格数据(数字和文本),文件的每一行都是一个数据记录。每个记录由一个或多个字段组成,用逗号分隔。
pandas
iloc[]
基于整数位置的索引,用于按位置选择
fillna()
用指定的方法填充NA/NaN值
1
| DataFrame.fillna(value=None, *, method=None, axis=None, inplace=False, limit=None, downcast=<no_default>)
|
get_dummies()
one-hot 独热编码
将离散型特征的每一种特征取值都看成一种状态,若指定离散特征中有N个不相同的取值,那么我们就可以将该特征抽象成N种不同的状态,one-hot编码保证了每一个取值只会使得一种状态处于“激活态”,也就是说这N种状态中只有一个状态位值为1,其他状态位都是0
1
| pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None)
|
data
:输入的数据
dummy_na
:增加一列表示空缺值,如果False就忽略空缺值(默认false)
numpy
astype()
用于执行类型转换操作
1
| series.astype(dtype, copy=True, errors='raise')
|
dtype
:表示要转换的目标数据类型
copy
:
True
:(默认)表示创建数据的副本
False
:可能会修改原始数据
errors
:
raise
(默认)在转换过程中遇到错误抛出异常
ignore
忽略错误