本文主要是学习李沐:动手学深度学习2.0在线课程的笔记。
视频地址:https://zhuanlan.zhihu.com/p/29125290。
教材全本:https://zh-v2.d2l.ai/
本课教材:https://zh-v2.d2l.ai/chapter_preliminaries/pandas.html
笔记地址:https://gitee.com/lhm8013609/mldl_-learning-notes/tree/master/1%E3%80%81DL_Limu/Notes
2021.05.08 数据预处理学习
os文件/目录方法模块学习
举一个例子,我们首先创建一个人工数据集,并存储在csv(逗号分隔值)文件 …/data/house_tiny.csv 中。以其他格式存储的数据也可以通过类似的方式进行处理。下面的mkdir_if_not_exist 函数可确保目录 …/data 存在。注意,注释 #@save是一个特殊的标记,该标记下方的函数、类或语句将保存在 d2l 软件包中,以便以后可以直接调用它们(例如 d2l.mkdir_if_not_exist(path))而无需重新定义。
import os
# os.makedirs() 方法用于递归创建目录
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')
Note:
os.makedirs() 方法用于递归创建目录
- makedirs()方法语法格式如下:
os.makedirs(path, mode=0o777) - 参数
path – 需要递归创建的目录,可以是相对或者绝对路径。
mode – 权限模式。
os.path.join()函数用于路径拼接文件路径
- 路径表示
.
表示当前目录..
表示当前目录的上一级目录。./
表示当前目录下的某个文件或文件夹,视后面跟着的名字而定../
表示当前目录上一级目录的文件或文件夹,视后面跟着的名字而定。
* os.path.join(‘…’, ‘data’) 表示路径…data,实际是在当前目录创建data文件夹
- 会从第一个以”/”开头的参数开始拼接,之前的参数全部丢弃。
- 以上一种情况为先。在上一种情况确保情况下,若出现”./”开头的参数,会从”./”开头的参数的上一个参数开始拼接。
- 有多个以”/”开头的参数,从最后”/”开头的的开始往后拼接,之前的参数全部丢弃
- !!!注意:Linux下和Windows下有所区别,这是基于Windows下的结论,见评论:python路径拼接os.path.join()函数完全教程
- os.path.join(‘…’, ‘data’, ‘house_tiny.csv’) 表示当前目录的data文件夹下的house_tiny.csv文件的目录
with open(data_file, ‘w’) as f: f.write()
- 文件的写操作;
- 相关用法见:
- python 使用 with open() as 读写文件;
- with open() as f 用法
import os
# windows环境下,结果如上所述,结论正确
print("1:",os.path.join('aaaa','/bbbb','ccccc.txt'))
print("2:",os.path.join('/aaaa','/bbbb','/ccccc.txt'))
print("3:",os.path.join('aaaa','./bbb','ccccc.txt'))
输出:
1: /bbbb\ccccc.txt
2: /ccccc.txt
3: aaaa\./bbb\ccccc.txt
读取文件:
import pandas as pd
data = pd.read_csv(data_file)
data
输出:
NumRooms Alley Price
0 NaN Pave 127500
1 2.0 NaN 106000
2 4.0 NaN 178100
3 NaN NaN 140000
2.2.2. 处理缺失值
注意,“NaN” 项代表缺失值。为了处理缺失的数据,典型的方法包括 插值 和 删除,其中插值用替代值代替缺失值。而删除则忽略缺失值。在这里,我们将考虑插值。
通过位置索引iloc,我们将 data 分成 inputs 和 outputs,其中前者为 data的前两列,而后者为 data的最后一列。对于 inputs 中缺少的的数值,我们用同一列的均值替换 “NaN” 项。
# iloc[:,:],逗号前是行,后是列,
# :表示从哪行(列)到哪行(列),如下面的0:2即表示0-2列
# 第二列,即最后一列
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())
print(inputs)
输出:
NumRooms Alley
0 3.0 Pave
1 2.0 NaN
2 4.0 NaN
3 3.0 NaN
Note:
iloc函数:通过行号来取行数据(如取第二行的数据)
- data.iloc[:, 0:2] 取data的所有行的0-2列
- loc函数:通过行索引 “Index” 中的具体值来取行数据(如取"Index"为"A"的行)
- 更多:Pandas中loc和iloc函数用法详解(源码+实例)
fillna(),mean()函数
-
fillna函数形式:fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
-
参数:
-
value:用于填充的空值的值。
扫描二维码关注公众号,回复: 17000189 查看本文章 -
mean()函数功能:求取均值:python 的numpy库中的mean()函数用法
-
经常操作的参数为axis,以m * n矩阵举例:
axis 不设置值,对 mn 个数求均值,返回一个实数
axis = 0:压缩行,对各列求均值,返回 1 n 矩阵
axis = 1 :压缩列,对各行求均值,返回 m *1 矩阵 -
mean(A)
若A为矩阵,则输出每一列的均值(一个向量)
若A为列向量,则输出均值(一个数)
若A为行向量,则也是输出均值(一个数),和列向量一样
使用jupyter notebook编辑文本和代码:使用jupyter notebook编辑文本和代码
- enter两行既是空一行
- 按两次dd可以删除单元格
对于 inputs 中的类别值或离散值,我们将 “NaN” 视为一个类别。由于 “巷子”(“Alley”)列只接受两种类型的类别值 “Alley” 和 “NaN”,pandas 可以自动将此列转换为两列 “Alley_Pave” 和 “Alley_nan”。巷子类型为 “Pave” 的行会将“Alley_Pave”的值设置为1,“Alley_nan”的值设置为0。缺少巷子类型的行会将“Alley_Pave”和“Alley_nan”分别设置为0和1。
inputs = pd.get_dummies(inputs, dummy_na=True)
print(inputs)
NumRooms Alley_Pave Alley_nan
0 3.0 1 0
1 2.0 0 1
2 4.0 0 1
3 3.0 0 1
Note
pd.get_dummies,
官方文档: 点这
-
pd.get_dummies(inputs, dummy_na=True)
-
默认按值分为几列,同时dummy_na=True表示用bool值表示具体值
-
以上只有pave和NAN两种值,所以分为两列,同时pave用1表示,NAN用0表示
-
对分类型变量,进行编码处理——pd.get_dummies()、LabelEncoder()、oneHotEncoder():点这
2021.05.11
2.2.3. 转换为张量格式
现在 inputs 和 outputs 中的所有条目都是数值类型,它们可以转换为张量格式。当数据采用张量格式后,可以通过在 2.1节 中引入的那些张量函数来进一步操作。
import torch
x, y = torch.tensor(inputs.values), torch.tensor(outputs.values)
x, y
输出:
(tensor([[3., 1., 0.],
[2., 0., 1.],
[4., 0., 1.],
[3., 0., 1.]], dtype=torch.float64),
tensor([127500, 106000, 178100, 140000]))
Note:inputs就是前面的房间号(NumRooster)、巷子(Alley)这些,而outputs就是价格price
2.2.4. 小结
像庞大的 Python 生态系统中的许多其他扩展包一样,pandas 可以与张量兼容。
插值和删除可用于处理缺失的数据。
2.2.5. 练习
创建包含更多行和列的原始数据集。
删除缺失值最多的列。
将预处理后的数据集转换为张量格式。
作业:
# 1、创建原始数据集
import os
p_datafile = os.path.join('..', 'data', 'house.csv')
with open(p_datafile, 'w') as f:
f.write('NumRoos,Alley,Size,Garden,Price\n')
f.write('NA,Pave,100,Yes,127500\n')
f.write('2,NA,200,Yes,187500\n')
f.write('3,NA,150,No,155500\n')
f.write('NA,NA,90,NA,100500\n')
f.write('4,Pave,120,Yes,137500\n')
import pandas as pd
data1 = pd.read_csv(p_datafile)
data1
输出:
NumRoos Alley Size Garden Price
0 NaN Pave 100 Yes 127500
1 2.0 NaN 200 Yes 187500
2 3.0 NaN 150 No 155500
3 NaN NaN 90 NaN 100500
4 4.0 Pave 120 Yes 137500
Note:处理缺失值
- df.isnull()#是缺失值返回True,否则范围False
- df.isnull().sum()#返回每列包含的缺失值的个数
- df.dropna()#直接删除含有缺失值的行
- df.dropna(axis = 1)#直接删除含有缺失值的列
- df.dropna(how = ‘all’)#只删除全是缺失值的行
- df.dropna(thresh = 4)#保留至少有4个缺失值的行
- df.dropna(subset = [‘C’])#删除含有缺失值的特定的列
- dddf = ddf.dropna(subset=[‘jie_num’],axis=0)#删除含有缺失值的特定的行
- datanota = AData[AData[‘marital’].notna()]#删除某列中含有缺失值的行
* df.dropna()的Parameters说明:
DataFrame.dropna(axis=0, how=‘any’, thresh=None, subset=None, inplace=False)
- axis 0为行 1为列,default 0,数据删除维度
- how {‘any’, ‘all’}, default ‘any’,any:删除带有nan的行;all:删除全为nan的行
- thresh int,保留至少 int 个非nan行
- subset list,在特定列缺失值处理
- inplace bool,是否修改源文件
End
data1.isna().sum()# 返回每列包含的缺失值的个数
输出:
NumRoos 2
Alley 3
Size 0
Garden 1
Price 0
dtype: int64
# 2、删除缺失值最多的列
data1 = data1.dropna(axis=1, thresh=max(data1.isna().sum()))
# data1.dropna(axis=1, thresh=3)# 将在列的方向上三个为NaN的项删除
data1 = data1.fillna(data1.mean())# 将数值的空值填充为已有数值的平均值
data1
输出:
NumRoos Size Garden Price
0 3.0 100 Yes 127500
1 2.0 200 Yes 187500
2 3.0 150 No 155500
3 3.0 90 NaN 100500
4 4.0 120 Yes 137500
input1, output1 = data1.iloc[:, 0:3], data1.iloc[:,3]
input1, output1
输出:
( NumRoos Size Garden
0 3.0 100 Yes
1 2.0 200 Yes
2 3.0 150 No
3 3.0 90 NaN
4 4.0 120 Yes,
0 127500
1 187500
2 155500
3 100500
4 137500
Name: Price, dtype: int64)
input1 = pd.get_dummies(input1, dummy_na=True) # 按值将Garden分为3列
input1
输出:
NumRoos Size Garden_No Garden_Yes Garden_nan
0 3.0 100 0 1 0
1 2.0 200 0 1 0
2 3.0 150 1 0 0
3 3.0 90 0 0 1
4 4.0 120 0 1 0
# 3、将其转换为张量格式
import torch
a, b = torch.tensor(input1.values), torch.tensor(output1.values)
a, b
输出:
(tensor([[ 3., 100., 0., 1., 0.],
[ 2., 200., 0., 1., 0.],
[ 3., 150., 1., 0., 0.],
[ 3., 90., 0., 0., 1.],
[ 4., 120., 0., 1., 0.]], dtype=torch.float64),
tensor([127500, 187500, 155500, 100500, 137500]))
torch.Tensor和torch.tensor的区别
在Pytorch中,Tensor和tensor都用于生成新的张量。
a = torch.Tensor([1, 2])
a
a=torch.tensor([1,2])
a
首先我们从根源上来看看torch.Tensor()和torch.tensor()区别。
torch.Tensor
torch.Tensor()是Python类,更明确的说,是默认张量类型torch.FloatTensor()的别名,torch.Tensor([1,2]) 会调用Tensor类的构造函数__init__,生成单精度浮点类型的张量。
a=torch.Tensor([1,2])
a.type()
torch.tensor()
torch.tensor()仅仅是Python的函数,函数原型是:
torch.tensor(data, dtype=None, device=None, requires_grad=False)
其中data可以是:list, tuple, array, scalar等类型。
torch.tensor()可以从data中的数据部分做拷贝(而不是直接引用),根据原始数据类型生成相应的torch.LongTensor,torch.FloatTensor,torch.DoubleTensor。
import numpy as np
a = torch.tensor([1, 2])
a.type()
输出:
'torch.LongTensor'
b = torch.tensor([1., 2.])
b.type()
输出:
'torch.FloatTensor'
c = np.zeros(2, dtype=np.float64)
c = torch.tensor(c)
c.type()
输出:
'torch.DoubleTensor'
a, b=torch.Tensor(1), torch.Tensor([1])
a, b
输出:
(tensor([1.4013e-45]), tensor([1.]))
前者的标量1是作为size传入的,后者的向量1是作为value传入的
# astype函数用于array中数值类型转换
x = np.array([1, 2, 2.5])
x.astype(int)
输出:
array([1, 2, 2])
更多见:深入浅出之dtype( )和astype( )函数:点这
若有不当之处,请指教!更多资料请关注【公z号:龙一的编程life】