深度学习-李沐-第二节-数据处理与操作
数据操作及数据预处理
定义
n维数组,也称为张量(tensor)。张量类(在MXNet中为ndarray,在PyTorch和TensorFlow中为Tensor) 都与Numpy的ndarray类似。但深度学习框架⼜⽐Numpy的ndarray多⼀些重要功能:⾸先,GPU很好地⽀持加速计算,⽽NumPy仅⽀持CPU计算;其次,张量类⽀持⾃动微分。这些功能使得张量类更适合深度学习。
数据操作
创造张量
x = torch.arange(12)
print(x)
print(x.shape)
print(x.numel())
# 改变x的形状。一维变二维
y = x.reshape(3, 4)
print(y)
print(y.shape)
print(y.numel())
zeros = torch.zeros(3, 4)
ones = torch.ones(2, 3, 4)
print(zeros)
print(ones)
# 正态分布
z = torch.randn(3, 4)
print(z)
t1 = torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
print(t1)
运算符
op1 = torch.tensor([1.0, 2, 4, 8])
op2 = torch.tensor([2, 2, 2, 2])
print(op1 + op2)
print(op1 - op2)
print(op1 * op2)
print(op1 / op2)
print(op1 ** op2)
张量连结与比较
X = torch.arange(12).reshape((3, 4))
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
print(torch.cat((X, Y), dim=0))
print(torch.cat((X, Y), dim=1))
X1 = torch.cat((op1, op2), dim=0)
Y1 = torch.cat((op1, op2), dim=-1)
print(X1)
print(Y1)
a = torch.tensor([[[0, 1], [1, 1]], [[2, 2], [3, 2]]])
b = torch.tensor([[[0, 1], [1, 1]], [[2, 2], [3, 2]]])
print(torch.cat((a, b), dim=2))
print(torch.cat((a, b), dim=1))
print(torch.cat((a, b), dim=0))
print(a == b)
print(a.sum())
n维张量的dim取值[-n,n-1],0表示从第一个维度连结,-1表示从最后一个维度连结(与n-1同效)
广播机制与切片索引
# 广播机制 a复制行 b复制列 然后相加
a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
# 索引和切片
# 最后一个元素
print(x[-1])
# 第二到第三个元素 左开右闭
print(x[1:3])
# 写入元素到矩阵
X[2, 3] = 101
X[0:2, :] = 12
节省内存与转换对象
# 节省内存
a1 = torch.arange(12).reshape((3, 4))
b1 = torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
print(id(a1)) # 2122406153888
print(id(b1)) # 2122406153328
a = a + b
print(id(a)) # 2552922129648
# 由此可见是三个内存地址 +=运算不会新开辟内存 a1[:] = a1 + b1也不会新开辟内存
# a1 += b1
# print(id(a1)) #2548818894096
a1[:] = a1 + b1
print(id(a1)) # 2298562731120
c1 = torch.zeros_like(a1)
print(id(c1)) # 2181536472576
c1[:] = a1 + b1
print(id(c1)) # 2181536472576
# 转换为其他对象
print(type(X)) # <class 'torch.Tensor'>
A = X.numpy()
B = torch.tensor(A)
print(type(A)) # <class 'numpy.ndarray'>
print(type(B)) # <class 'numpy.ndarray'>
数据预处理
读取数据集
创建数据
os.makedirs(os.path.join('..', 'data'), exist_ok=True) # 在上级目录创建data文件夹
datafile = os.path.join('..', 'data', 'house_tiny.csv') # 创建文件
with open(datafile, 'w') as f: # 往文件中写数据
f.write('NumRooms,Alley,Price\n') # 列名
f.write('NA,Pave,127500\n') # 第1行的值
f.write('2,NA,106000\n') # 第2行的值
f.write('4,NA,178100\n') # 第3行的值
f.write('NA,NA,140000\n') # 第4行的值
读取数据
# 读取数据集
data = pd.read_csv(datafile) # 可以看到原始表格中的空值NA被识别成了NaN
print('1.原始数据:\n', data)
处理缺失值
处理缺失值
1.用fillna()填充缺失值
2.利用pandas中的get_dummies函数来处理离散值或者类别值
# 处理缺失值
inputs = data.iloc[:, 0:2]
outputs = data.iloc[:, 2]
# 用均值填充NumRooms
inputs = inputs.fillna(inputs.mean())
print(inputs)
print("-----------------------------")
print(outputs)
# 利用pandas中的get_dummies函数来处理离散值或者类别值。
# [对于 inputs 中的类别值或离散值,我们将 “NaN” 视为一个类别。] 由于 “Alley”列只接受两种类型的类别值 “Pave” 和 “NaN”
inputs = pd.get_dummies(inputs, dummy_na=True)
print('2.利用pandas中的get_dummies函数处理:\n', inputs)
转换为张量格式
X, y = torch.tensor(inputs.values), torch.tensor(outputs.values)
print(X)
print(y)
扩展
关于fillna()函数的扩展
df1 = pd.DataFrame([[1, 2, 3], [NaN, NaN, 2], [NaN, NaN, NaN], [8, 8, NaN]]) # 创建初始数据
print(df1)
print(df1.fillna(100)) # 用常数填充 ,默认不会修改原对象
print(df1.fillna({0: 10, 1: 20, 2: 30})) # 通过字典填充不同的常数,默认不会修改原对象
print(df1.fillna(method='ffill')) # 用前面的值来填充
print(df1.fillna(0, inplace=True)) # inplace= True直接修改原对象
df2 = pd.DataFrame(np.random.randint(0, 10, (5, 5))) # 随机创建一个5*5
df2.iloc[1:4, 3] = NaN
df2.iloc[2:4, 4] = NaN # 指定的索引处插入值
print(df2)
print(df2.fillna(method='bfill', limit=2)) # 限制填充个数
print(df2.fillna(method="ffill", limit=1, axis=1)) # 传入axis=” “修改填充方向