本文主要是学习李沐:动手学深度学习2.0在线课程的笔记。
视频地址:https://zhuanlan.zhihu.com/p/29125290。
教材全本:https://zh-v2.d2l.ai/
本课教材:https://zh-v2.d2l.ai/chapter_preliminaries/pandas.html
笔记地址:https://github.com/LongHaoMing/LiMu_DeepLearningV2
举一个例子,我们首先创建一个人工数据集,并存储在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')
.
表示当前目录..
表示当前目录的上一级目录。./
表示当前目录下的某个文件或文件夹,视后面跟着的名字而定../
表示当前目录上一级目录的文件或文件夹,视后面跟着的名字而定。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
注意,“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
fillna函数形式:fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
参数:
value:用于填充的空值的值。
更多参数:pandas 用均值填充缺失值NaN | fillna 方法解析
mean()函数功能:求取均值:python 的numpy库中的mean()函数用法
经常操作的参数为axis,以m * n矩阵举例:
axis 不设置值,对 mn 个数求均值,返回一个实数
axis = 0:压缩行,对各列求均值,返回 1 n 矩阵
axis = 1 :压缩列,对各行求均值,返回 m *1 矩阵
mean(A)
若A为矩阵,则输出每一列的均值(一个向量)
若A为列向量,则输出均值(一个数)
若A为行向量,则也是输出均值(一个数),和列向量一样
对于 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
pd.get_dummies(inputs, dummy_na=True)
默认按值分为几列,同时dummy_na=True表示用bool值表示具体值
以上只有pave和NAN两种值,所以分为两列,同时pave用1表示,NAN用0表示
对分类型变量,进行编码处理——pd.get_dummies()、LabelEncoder()、oneHotEncoder():点这
现在 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
像庞大的 Python 生态系统中的许多其他扩展包一样,pandas 可以与张量兼容。
插值和删除可用于处理缺失的数据。
创建包含更多行和列的原始数据集。
删除缺失值最多的列。
将预处理后的数据集转换为张量格式。
# 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
DataFrame.dropna(axis=0, how=‘any’, thresh=None, subset=None, inplace=False)
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]))
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()仅仅是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】