稀疏张量表示为一对稠密张量:一个值张量和一个二维指标张量(每一维中存储多个值)。一个稀疏张量可以通过提供这两个张量,以及稀疏张量的大小来构造
利用np.array()转换成nadrray类型数据,输出shape属性即可
torch.mul(a, b)是矩阵a和b对应位相乘,a和b的维度必须相等,比如a的维度是(1, 2),b的维度是(1, 2),返回的仍是(1, 2)的矩阵
torch.mm(a, b)是矩阵a和b矩阵相乘,比如a的维度是(1, 2),b的维度是(2, 3),返回的就是(1, 3)的矩阵
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
x1 = torch.tensor([0,2,3,4,5])
x2 = torch.tensor([[0.5,0.4,0.3],[0.5,0.5,0.5],[0.1,0.1,0.1],[0.2,0.7,0.9],[0.3,0.4,0.6],[0.5,0.5,0.5]])
print(x1)
print(x1.shape)
print(x2)
print(x2.shape)
x3 = F.embedding(x1,x2)
print(x3)
print(x3.shape)
特别提醒[注意Tensor大小写]
torch.from_numpy()将Numpy转为Tensor
torch.numpy()将Tensor转为Numpy
使用torch.Tensor()进行转换,发现Numpy的数据类型和Tensor的类型一致,共享内存
使用torch.Tensor()进行转换,发现Numpy的数据类型和Tensor的类型不一致,b与a不共享内存
使用torch.tensor()进行转换,只进行数据拷贝,不会共享内存
G=nx.from_numpy_matrix(A, parallel_edges=False, create_using=None)
A = np.array([[0,0,3], [2,0,0], [0,1,0]])
从邻接矩阵A创建有向权重图,节点标号为[0,1,2]
G = nx.from_numpy_matrix(A,create_using=nx.DiGraph())
Python中通过Key访问字典,当Key不存在时,会引发‘KeyError’异常。为了避免这种情况的发生,可以使用collections类中的defaultdict()方法来为字典提供默认值。
该函数返回一个类似字典的对象。defaultdict是Python内建字典类(dict)的一个子类,它重写了方法_missing_(key),增加了一个可写的实例变量default_factory,实例变量default_factory被missing()方法使用,如果该变量存在,则用以初始化构造器,如果没有,则为None。其它的功能和dict一样。
第一个参数为default_factory属性提供初始值,默认为None;其余参数包括关键字参数(keyword arguments)的用法,和dict构造器用法一样。
ndarry 转 csr_matrix
>>> import numpy as np
>>> from scipy import sparse
>>> A = np.array([[1,2,0],[0,0,3],[1,0,4]])
>>> A
array([[1, 2, 0],
[0, 0, 3],
[1, 0, 4]])
>>> sA = sparse.csr_matrix(A) # Here's the initialization of the sparse matrix.
>>> sA
<3x3 sparse matrix of type 'numpy.int32'>'
with 5 stored elements in Compressed Sparse Row format>
>>> print sA
(0, 0) 1
(0, 1) 2
(1, 2) 3
(2, 0) 1
(2, 2) 4
csr_matrix 转 ndarray
>>> import numpy as np
>>> import scipy.sparse
>>> my_matrix = scipy.sparse.csr_matrix((2,2))
>>> my_array = my_matrix.A
>>> type(my_array)
numpy.ndarray
scipy.sparse包下的稀疏矩阵有多种:
csr, csc, lil, dok和不支持位置索引取值的 coo, dia。
ndarray->lil_matrix
features = sp.coo_matrix(features).tolil()
List转Numpy:numpy.array(list)
Numpy转List:array.tolist()
np.array()、np.ones()、np.zeros()、np.eye()、np.random.rand()
输出numpy类型数据的维度:x.shape
输出numpy类型数据的元素个数:x.size
输出numpy类型数据的元素类型:x.dtype
输出numpy类型数据的维度:x.ndim
# 创建一维的narray对象
a_1 = np.array([1,2,3,4,5])
print('a_1\n',a_1)
print('a_1.shape',a_1.shape,' a_1.size:',a_1.size)
# 创建二维的narray对象
a_2 = np.array([[1,2,3,4,5],[6,7,8,9,10]])
print('a_2\n',a_2)
print('a_2.shape',a_2.shape,' a_2.size:',a_2.size)
# 创建全1矩阵
a_3 = np.ones((2,3))
print('a_3\n',a_3)
print('a_3.shape',a_3.shape,' a_3.size:',a_3.size)
# 创建全0矩阵
a_4 = np.zeros((2,3))
print('a_4\n',a_4)
print('a_4.shape',a_4.shape,' a_4.size:',a_4.size)
# 创建单位矩阵
a_5 = np.eye(4)
print('a_5\n',a_5)
print('a_5.shape',a_5.shape,' a_5.size:',a_5.size)
# 创建空矩阵
a_6 = np.empty((2,3))
print('a_6\n',a_6)
print('a_6.shape',a_6.shape,' .size:',a_6.size)
# 创建随机矩阵
a_7 = np.random.rand(5,5)
print('a_7\n',a_7)
print('a_7.shape',a_7.shape,' a_7.size:',a_7.size)
# 从本地读取numpy类型数据
# 存储/读取.npy文件
a_8 = np.random.rand(5,5)
np.save('a_8',a_8)
a_9 = np.load('a_8.npy')
print('a_8\n',a_8)
print('a_8.shape',a_8.shape,' a_8.size:',a_8.size)
print('a_9\n',a_9)
print('a_9.shape',a_9.shape,' a_9.size:',a_9.size)
# 存储/读取.txt文件
a_10 = np.random.rand(5,5)
np.savetxt('a_10.txt',a_8,delimiter=',')
a_11 = np.loadtxt('a_10.txt',delimiter=',')
print('a_10\n',a_10)
print('a_10.shape',a_10.shape,' a_10.size:',a_10.size)
print('a_11\n',a_11)
print('a_11.shape',a_11.shape,' a_11.size:',a_11.size)
axis=i,则numpy沿着第i个下标变化的方向进行操作.
第0维=第0个下标=行.
第1维=第1个下标=列.
axis=0,则沿着第0维(行)变化的方向 即竖向;
axis=1,则沿着第1维(列)变化的方向 即横向.
a.flatten():a是个数组,a.flatten()就是把a降到一维,默认是按行的方向降 。
a.flatten().A:a是个矩阵,降维后还是个矩阵,矩阵.A(等效于矩阵.getA())变成了数组
## 矩阵的乘法运算(点乘)
a1 = np.array([[1,2,3],[4,5,6]]) # a1为2*3矩阵
a2 = np.array([[1,2],[3,4],[5,6]]) # a2为3*2矩阵
a3 = a1.dot(a2)
print('a3\n',a3)
print('a3.size',a3.size,' ae.shape',a3.shape)
## 矩阵的转置(transpose或T)
a4=np.array([[1,2,3],
[4,5,6]])
print('a4\n',a4.transpose())
print('a4.transpose().shape', a4.transpose().shape)#或np.transpose(array)
print('a4\n',a4.T)
print('a4.T.shape', a4.T.shape)
## 矩阵的逆
import numpy.linalg as lg
a5 = np.array([[6,2,3],[4,5,6],[7,8,9]])
print('lg.inv(a5)\n',lg.inv(a5))
## 最大值、最小值
a6=np.array([[1,2,3],
[4,5,6]])
print('a6.max()',a6.max())#结果为6
print('a6,min()',a6.min())#结果为1
#同时还可以指定axis关键字,获取行或列的最大、最小值
print('a6.max(axis=0)',a6.max(axis=0)) #x轴最大值,0,1分别代表行列
print('a6.max(axis=1)',a6.max(axis=1)) #x轴最大值,0,1分别代表行列
## 平均值
a7=np.array([[1,2,3],
[4,5,6]])
print('a7.mean()',a7.mean())#结果为3.5
print('np.average(a7)',np.average(a7))#结果为3.5
print('a7.mean(axis=0)',a7.mean(axis=0))#行方向的平均值,同样,0,1代表维度
## 方差 方差的函数为var(),方差函数var()相当于函数mean(abs(x - x.mean())**2),其中x为矩阵
a8=np.array([[1,2,3],
[4,5,6]])
print('a8.var()',a8.var())#结果为2.91666666667
#同样可通过axis指定维度0,1分别代表行列,
print('a8.var(axis=0)',a8.var(axis=0))
## 标准差 std()相当于sqrt(mean(abs(x - x.mean())**2)),或相当于sqrt(x.var())
a9=np.array([[1,2,3],
[4,5,6]])
print('a9.std()',a9.std())#结果为1.70782512766
#同样可通过axis指定维度0,1分别代表行列,
print('a9.std(axis=0)',a9.std(axis=0))
## 求和
a10=np.array([[1,2,3],
[4,5,6]])
print('a10.sum()',a10.sum())#结果:21
#指定维度
print('a10.sum(axis=0)',a10.sum(axis=0))
## 按条件截取应用较多的是对矩阵中满足一定条件的元素变成特定的值
a11 = np.array([[1,2,3,4,5],[6,7,8,9,10]])
print('a11\n',a11)
a11[a11>6] = 0
print('a11\n',a11)
## clip(矩阵,min,max)#返回值:所有小于min的值都等于min,所有大于max的值都等于max
a12=np.array([[1,2,3],
[4,5,6]])
print('a12.clip(2,4)\n',a12.clip(2,4))
## 矩阵的合并
a13 = np.array([[1,2],[3,4]])
a14 = np.array([[5,6],[7,8]])
#!注意 参数传入时要以列表list或元组tuple的形式传入
#横向合并,返回结果如下
print('np.hstack([a1,a2])\n',np.hstack([a13,a14])) # np.concatenate( (a1,a2), axis=1 ) 等价于 np.hstack( (a1,a2) )
#纵向合并,返回结果如下
print('np.vstack((a1,a2))\n',np.vstack((a13,a14))) # np.concatenate( (a1,a2), axis=0 ) 等价于 np.vstack( (a1,a2) )
## 矩阵维度变换(维度变换的两个矩阵size必须相同)
a15 = np.array([[1,2,3,4],[5,6,7,8],[11,12,13,14]])
print('a15\n',a15)
a16 = a15.reshape(4,3)
print('a16\n',a16)
a17=array([[1,2],[3,4],[5,6]])
print(a17.flatten()) #默认按行的方向降维
print(a17.flatten('F')) #按列降维
print(a17.flatten('A')) #按行降维
输出tensor张量的维度大小信息 a.size()与a.shape作用相同
torch.Tensor([])、torch.eye()、torch.zeos()、torch.linspace()、torch.rand()
# 根据list数据生成tensor
torch.Tensor([1,2,3,4,5,6])
#根据指定形状生成tensor
torch.Tensor(2,3)
#根据给定的形状生成torch
t = torch.Tensor([[1,2,3],[4,5,6]])
print(t)
# tensor张量的维度大小信息
t.size()
print(t.shape)
# 根据已知大小创建tensor
torch.Tensor(t.size())
注意:
t1 = torch.Tensor(1)
t2 = torch.tensor(1)
print("t1的值{},t1的数据类型{}".format(t1,t1.type()))
print("t2的值{},t2的数据类型{}".format(t2,t2.type()))
# 生成单位矩阵
t3 = torch.eye(2,2)
# 生成全部是0的矩阵
t4 = torch.zeros(2,3)
# 根据规则生成数据
t5 = torch.linspace(1,10,4)
# 生成满足均匀分布随机数
t6 = torch.rand(2,3)
# 返回所给数据形状相同,值全部为0的张量
t7 = torch.zeros_like(torch.rand(2,3))
print("单位矩阵:{},/n 零矩阵:{},/n规则数据格式“”")
a.shape、a.size()、a.dim()、a.view(x1,x2(-1))、torch.unsqueeze(a,axis)、torch.cat(x,dim)、torch.stack(x, dim=0)
.cat 和 .stack的区别在于 cat会增加现有维度的值,可以理解为续接,stack会新加增加一个维度,可以理解为叠加
# size——返回tensor的属性值,与shape等价
shape_test = torch.randn(2,3)
# shape——查看属性
print(shape_test.shape)
print(shape_test.size())
# dim——查看维度
print(shape_test.dim())
# view——改变维度(注意数据量不变)
print(shape_test.view(3,2))
print(shape_test.view(-1)) # 展开为一维向量
# unsqueeze——添加维度,后面的参数为需要添加维度的维数
new_shape_test = torch.unsqueeze(shape_test,0)
print(new_shape_test)
print("原始维度:{}".format(shape_test.shape))
print("添加后的维度:{}".format(new_shape_test.shape))
# 按照已经存在的维度进行concatenate--cat
x = torch.randn(2, 3)
print(torch.cat((x, x, x), 0))
print(torch.cat((x, x, x), 0).shape)
# 按照新的维度进行concatenate--stack
a = torch.IntTensor([[1,2,3],[11,22,33]])
b = torch.IntTensor([[4,5,6],[44,55,66]])
c = torch.stack([a,b],0)
d = torch.stack([a,b],1)
e = torch.stack([a,b],2)
print(c.shape)
print(d.shape)
print(e.shape)
torch.gather方法
torch.gather(input, dim, index, out=None) → Tensor
以二维数组为例
当dim=0,相当于在第一维度变换的方向进行操作,也就是按列操作。此时原数据input存在几列则决定了index的列数。
当dim=1,相当于在第二维度变换的方向进行操作,也就是按行操作。此时原数据input存在几行则决定了index的行数。
上述规则可以理解为,因为axis决定了索引的方式,且每一行或一列进行一次索引,如果index的维度超过了索引的维度次数则会产生错误,但是同一维度中的索引次数却不受限制。
# manual_seed()——设置随机种子
torch.manual_seed(100)
index_test = torch.rand(2,3)
print("原始数据:{}".format(index_test))
# []——获取切片数据
print("第一行数据:{}".format(index_test[0,:]))
print("最后一列数据:{}".format(index_test[:,-1]))
# 索引
mask =index_test>0 #根据原始数据建立索引
print(torch.masked_select(index_test,mask)) #根据索引获取值
print(torch.nonzero(mask)) #获取非零数值的下标
# torch.gather——按照规定的格式、方式进行索引
#out[i][j] = input[index[i][j]][j] # if dim == 0
#out[i][j] = input[i][index[i][j]] # if dim == 1
index1 = torch.LongTensor([[0,0,0],[1,1,1],[1,1,0]])
a = torch.gather(index_test,0,index1) # index_test是数据;dim=0表示按行索引,dim=1表示按列索引;index的大小就是输出的大小
print("按行索引结果(index的列数对应原始矩阵的列数):{}".format(a))
index2 = torch.LongTensor([[2,2,2,2],[2,1,1,1]])
b = torch.gather(index_test,1,index2)
print("按列索引结果(index的行数对应原始矩阵的列数):{}".format(b))
# torch.scatter_是与gather相反的一个操作
out_index = torch.zeros(2,4)
out_index.scatter_(1,index,b) #dim=1,index2是索引,b是按索引得到的值
print("将索引得到的值放回到相应的位置上(还原原始数据):{}".format(out_index))
根据行列索引访问矩阵中对应位置的元素
import torch
torch.manual_seed(100)
test_index = torch.rand(1,12).view(3,4)
row_index = [0,1,2]
col_index = [1,2,3]
print(test_index)
print(test_index[row_index, col_index])
ss
torch.tensor(data, dtype=None, device=None, requires_grad=False)
torch.as_tensor(data, dtype=None, device=None)
torch.from_numpy(ndarray)
torch.zeros(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
torch.ones(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
torch.eye(n, m=None, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
组合–拼接
torch.cat(seq, dim=0, out=None):按照已经存在的维度进行concatenate。
torch.stack(seq, dim=0, out=None):按照新的维度进行concatenate。
分块
torch.split(tensor, split_size_or_sections, dim=0):按照某个维度依照第二个参数给出的list或者int进行分割tensor。
索引
torch.split(tensor, split_size_or_sections, dim=0):按照某个维度依照第二个参数给出的list或者int进行分割tensor。
torch.masked_select(input, mask, out=None):按照mask输出一个一维的tensor。
torch.take(input, indices):将输入看成1D tensor,按照索引得到输出。输出大小与index大小一致。
torch.nonzero(input, out=None):输出非0元素的坐标。
torch.where(condition, x, y):按照条件从x和y中选出满足条件的元素组成新的tensor。
变形
torch.reshape(input, shape)
torch.t(input):只针对2D tensor转置
torch.transpose(input, dim0, dim1):交换两个维度
torch.squeeze(input, dim=None, out=None):去除那些维度大小为1的维度,如果输入张量的形状为(A×1×B×C×1×D),那么输出张量的形状为(A×B×C×D)
torch.unbind(tensor, dim=0):去除某个维度
torch.unsqueeze(input, dim, out=None):在指定位置添加维度
>>> '''
BSR矩阵中的inptr列表的第i个元素与i+1个元素是储存第i行的数据的列索引以及数据的区间索引,即indices[indptr[i]:indptr[i+1]]为第i行元素的列索引,data[indptr[i]: indptr[i+1]]为第i行元素的data。
在下面的例子中,对于第0行,indptr[0]:indptr[1] -> 0:2, 因此第0行的列为indice[0:2]=[0,2],data为data[0:2]=array([[[1, 1],[1, 1]],[[2, 2],[2, 2]]]),对应的就是最后结果的第0,1行。
'''
>>> indptr = np.array([0, 2, 3, 6])
>>> indices = np.array([0, 2, 2, 0, 1, 2])
>>> data = np.array([1, 2, 3, 4, 5, 6]).repeat(4).reshape(6, 2, 2)
>>> bsr_matrix((data,indices,indptr), shape=(6, 6)).toarray()
array([[1, 1, 0, 0, 2, 2],
[1, 1, 0, 0, 2, 2],
[0, 0, 0, 0, 3, 3],
[0, 0, 0, 0, 3, 3],
[4, 4, 5, 5, 6, 6],
[4, 4, 5, 5, 6, 6]])
>>> '''
不难发现,coo_matrix是可以根据行和列索引进行data值的累加。
'''
>>> row = np.array([0, 0, 1, 3, 1, 0, 0])
>>> col = np.array([0, 2, 1, 3, 1, 0, 0])
>>> data = np.array([1, 1, 1, 1, 1, 1, 1])
>>> coo_matrix((data, (row, col)), shape=(4, 4)).toarray()
array([[3, 0, 1, 0],
[0, 2, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 1]])
csc_matrix(arg1[, shape, dtype, copy])
Compressed Sparse Column matrix
csc_matrix的初始化方法可以是bsr_matrix的初始化方法,也可以是coo_matrix的初始化方法,该csc_matrix与下面的csr_matrix是比较常用的稀疏矩阵。
csr_matrix(arg1[, shape, dtype, copy])
Compressed Sparse Row matrix
csr_matrix的初始化与csc_matrix一致。
dia_matrix(arg1[, shape, dtype, copy])
Sparse matrix with DIAgonal storage
>>> #data定义对角线元素,在这里是[1,2,3,4]。
>>> data = np.array([[1, 2, 3, 4]]).repeat(3, axis=0)
>>> #offsets定义对角线的偏移量,0代表正对角线,正数代表往上偏移,负数代表往下偏移
>>> offsets = np.array([0, -1, 2])
>>> dia_matrix((data, offsets), shape=(4, 4)).toarray()
array([[1, 0, 3, 0],
[1, 2, 0, 4],
[0, 2, 3, 0],
[0, 0, 3, 4]])
>>> S = dok_matrix((5, 5), dtype=np.float32)
>>> for i in range(5):
... for j in range(5):
... S[i, j] = i + j
>>> S.toarray()
array([[0., 1., 2., 3., 4.],
[1., 2., 3., 4., 5.],
[2., 3., 4., 5., 6.],
[3., 4., 5., 6., 7.],
[4., 5., 6., 7., 8.]], dtype=float32)
lil_matrix(arg1[, shape, dtype, copy])
Row-based linked list sparse matrix
与dok_matrix类似,也是可以高效地插入元素更新矩阵。
spmatrixSparse([maxprint])
上面所有稀疏矩阵类型的基类型,不能被实例化
注意除最后一个基矩阵以外,其他七种稀疏矩阵都可以用以下方式(1、指定行索引、列索引以及对应的数据;2、指定array;3、稀疏矩阵之间的转化)来初始化,我们稀疏矩阵类型函数模板化为sparse_matrix。
>>> #行索引
>>> row = np.array([0, 3, 1, 0])
>>> #列索引
>>> col = np.array([0, 3, 1, 2])
>>> #具体数据
>>> data = np.array([4, 5, 7, 9])
>>> #第一种方式
>>> sparse_matrix((data, (row, col)), shape=(4, 4)).toarray()
array([[4, 0, 9, 0],
[0, 7, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 5]])
>>> #第二种方式(array可以是list,也可以是np.array)
>>> sparse_matrix(array).toarray()
>>> #第三种方式(sparse_matrix_other为其他稀疏矩阵类型,等价于sparse_matrix_other.tosparse(),具体的内函数形式根据需要转化的sparse_matrix类型而定)
>>> sparse_matrix(sparse_matrix_other).toarray()
内函数中有很多作用在矩阵元素的函数,下面列出一些函数。