N维数组
——是机器学习和神经网络的主要数据结构
创建数组
需要:形状(例如3*4的矩阵)、每个元素的数据类型(例如32位浮点数)、每个元素的值(例如全为0或随机数)
访问元素
数据操作实现:
import torch
# 张量表示一个数值组成的数组,这个数组可能有多个维度
x = torch.arange(12)
print(x)
# 可以通过张量的shape属性来访问张量的形状和张量中元素的总数
print(x.shape)
print(x.numel())
# 要改变一个张量的形状而不改变元素数量和元素值,我们可以调用reshape函数
X=x.reshape(3,4)
print(X)
# 使用全0、全1、其他常量或者从特定分布中随机采样的数字
print(torch.zeros((2,3,4)))
print(torch.ones((2,3,4)))
# 通过提供包含数值的Python列表(或嵌套列表)来为所需张量中的每个元素赋予确定值
y = torch.tensor([[2,1,4,3],[1,2,3,4],[4,3,2,1]])
print(y)
print(y.shape)
# 常见的标准算术运算符(+、-、*、/和**)都可以被升级为按元素运算
a = torch.tensor([1.0,2,4,8])
b = torch.tensor([2,2,2,2])
print(a+b,a-b,a*b,a/b,a**b,sep="\n") # **运算符是求幂运算
# 把多个张量连结在一起
c = torch.arange(12,dtype=torch.float32).reshape((3,4))
d = torch.tensor([[2.0,1,4,3],[1,2,3,4],[4,3,2,1]])
print(torch.cat((c,d),dim=0))
print(torch.cat((c,d),dim=1))
# 通过逻辑运算符构建二元张量
print(c==d)
# 对张量中的所有元素进行求和会产生一个只有一个元素的张量
print(c.sum())
# 即使形状不同,仍然可以通过调用广播机制(broadcasting mechanism)来执行按元素操作
e = torch.arange(3).reshape((3,1))
f = torch.arange(2).reshape((1,2))
print(e,f,sep="\n")
# e中的第一列三个元素被复制到第二列,f中第一行两个元素被复制到第二行和第三行
print(e+f)
# 可以用[-1]选择最后一个元素,可以用[1:3]选择第二个和第三个元素
print(c[-1], c[1:3])
# 除读取外,我们还可以通过指定索引来将元素写入矩阵
c[1,2] = 9
print(c)
# 为多个元素赋值相同的值,只需要索引所有元素,然后为它们赋值
c[0:2,:] = 12
print(c)
# 运行一些操作可能会导致为新结果分配内存
before = id(d)
d = d + c
print(id(d) == before)
# 执行原地操作(对元素进行改写,地址不变
z = torch.zeros_like(d)
print('id(z):',id(z))
z[:]=c+d
print('id(z):',id(z))
# 如果在后续计算中没有重复使用c,我们也可以使用c[:]=c+d或c+=d来减少操作的内存开销
before = id(c)
c+=d
print(id(c) == before)
# 转换为Numpy张量
A=c.numpy()
B=torch.tensor(A)
print(type(A),type(B))
# 将大小为1的张量转换为Python标量
a = torch.tensor([3.5])
print(a,a.item(),float(a),int(a))
数据预处理实现:
import os
import pandas as pd
import torch
# 创建一个人工数据集,并存储在csv(逗号分隔值)文件
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')
data = pd.read_csv(data_file)
print(data)
# 为了处理缺失的数据,典型的方法包括插值和删除,这里考虑插值
inputs,outputs = data.iloc[:,0:2],data.iloc[:,2] # 第一二列放到input里,第三列放到output里
inputs = inputs.fillna(inputs.mean()) # fillna对所有NaN填一个值(均值)
print(inputs)
# 对于inputs中的类别值或离散值,我们将“NaN”视为一个类别
inputs = pd.get_dummies(inputs,dummy_na=True)
print(inputs)
# 现在inputs和outputs中的所有条目都是数值类型,它们可以转换为张量格式。
X,y = torch.tensor(inputs.values),torch.tensor(outputs.values)
print(X,y,sep="\n")
课后练习:
数据操作:
运行本节中的代码。将本节中的条件语句X == Y
更改为X < Y
或X > Y
,然后看看你可以得到什么样的张量。
用其他形状(例如三维张量)替换广播机制中按元素操作的两个张量。结果是否与预期相同?
# 数据操作
# 1
X = torch.arange(12,dtype=torch.float32).reshape((3,4))
Y = torch.tensor([[2.0,1,4,3],[1,2,3,4],[4,3,2,1]])
print(X,Y,X==Y,XY,sep="\n")
#2(每个张量上必须至少有一个方向是1个元素的,否则无法复制)
Z = torch.arange(3).reshape((1,3,1))
W = torch.arange(8).reshape((4,1,2))
print(Z,W,sep="\n")
print(Z+W)
数据预处理:
创建包含更多行和列的原始数据集。
删除缺失值最多的列。
将预处理后的数据集转换为张量格式。
import os
import pandas as pd
import torch
# 创建包含更多行和列的原始数据集。
#
# 删除缺失值最多的列。
#
# 将预处理后的数据集转换为张量格式。
os.makedirs(os.path.join('..','data'),exist_ok=True)
data_file = os.path.join('..','data','school.csv')
with open(data_file,'w') as f:
f.write('Numclass,Name,Age,Grade\n') # 列名
f.write('NA,Tom,21,NA\n')
f.write('1,NA,19,NA\n')
f.write('1,NA,NA,NA\n')
f.write('2,Make,20,98\n')
f.write('4,Lili,18,NA\n')
# 读取数据集
data = pd.read_csv(data_file)
print(data)
a = data.isnull().sum(axis=0) # 每列的缺失值数量
print(a)
data.drop('Grade',axis=1) # 删除Grade这一列
print(data)
inputs,outputs = data.iloc[:,0:3],data.iloc[:,3]
inputs = inputs.fillna(inputs.mean())
inputs = pd.get_dummies(inputs,dummy_na=True)
x,y = torch.tensor(inputs.values),torch.tensor(outputs.values)
print(x,y,sep="\n")
代码可能还有一点问题,欢迎纠正