当前位置: 首页 > wzjs >正文

太和县建设银行网站seo在线培训课程

太和县建设银行网站,seo在线培训课程,好一点的网站建设,设计上海设计公司一、数组基础 导入 NumPy 时,通常给其一个别名“np”,即 import numpy as np。 NumPy 库中的函数,要在函数名前加上导入的库名 np. 才能使用。 数据类型 整数型数组与浮点型数组 为克服列表的缺点,一个 NumPy 数组只容纳一种数据类…

一、数组基

导入 NumPy 时,通常给其一个别名“np”,即 import numpy as np。

NumPy 库中的函数,要在函数名前加上导入的库名 np. 才能使用。

数据类

整数型数组与浮点型数组

为克服列表的缺点,一个 NumPy 数组只容纳一种数据类型,以节约内存。为方便起见,可将 NumPy 数组简单分为整数型数组与浮点型数组。

In [1] :

import numpy as np

In [2] :

# 创建整数型数组

arr1 = np.array( [1, 2, 3] ) # 元素若都是整数,则为整数型数组

print(arr1)

[1 2 3]

In [3] :

# 创建浮点型数组

arr2 = np.array( [1.0, 2, 3] ) # 内含浮点数,则为浮点型数组

print(arr2)

[1. 2. 3.]

注意,使用 print 输出 NumPy 数组后,元素之间没有逗号,这有两个好处,一是可以可将之与 Python 列表区分开来,二是避免逗号与小数点之间的混淆。

同化定理

一个人的力量是无法改变全体的,在实际操作中要注意:

  1. 往整数型数组里插入浮点数,该浮点数会自动被截断为整数;
  2. 往浮点型数组里插入整数,该整数会自动升级为浮点数;

In [1] :

import numpy as np

In [2] :

# 整数型数组

arr1 = np.array( [123] )

arr1[0] = 100.9 # 插入浮点数,被截断,数组仍为整数型

print(arr1)

[100 2 3]

In [3] :

# 浮点型数组

arr2 = np.array( [1.023] )

arr2[1] = 10 # 插入整数型,被升级,数组仍为浮点型

print(arr2)

[ 1. 10. 3.]

共同改变定理

同化定理告诉我们,整数型数组和浮点型数组之间的界限十分严格,那么如何将这两种数据类型的数组进行相互转化呢?既然某一个人容易被集体所同化,那只要全体共同改变,自然就可以成功。

整数型数组和浮点型数组相互转换,规范的方法是使用 .astype( ) 方法。

In [1] :

import numpy as np

In [2] :

# 整数型数组

arr1 = np.array( [123] )

print(arr1)

[1 2 3]

In [3] :

# 整数型数组 ——> 浮点型数组

arr2 = arr1.astype(float)

print(arr2)

[1. 2. 3.]

In [4] :

# 浮点型数组 ——> 整数型数组

arr3 = arr2.astype(int)

print(arr3)

[1 2 3]

除了上述方法,只要满足共同改变定理,整数型数组和浮点型数组仍然可以互相转换。最常见的是整数型数组在运算过程中升级为浮点型数组,示例如下。

In [1] :

import numpy as np

In [2] :

# 整数型数组

arr = np.array( [123] )

print(arr)

[1 2 3]

In [3] :

# 整数型数组与浮点数做运算

print( arr + 0.0 )

print( arr * 1.0 )

[1. 2. 3.]

[1. 2. 3.]

In [4] :

# 整数型数组遇到除法(即便是除以整数

print( arr / 1 )

[1. 2. 3.]

In [5] :

# 整数型数组与浮点型数组做运算

int_arr = np.array( [123] )

float_arr = np.array( [1.023] ) print( int_arr + float_arr )

[2. 4. 6.]

整数型数组很好升级,但浮点型数组在运算过程中一般不会降级。

数组维

一维数组与二维数组

考虑到深度学习中三维及其以上的数组出现次数少,我们后续主要讲解

NumPy 中的一维数组和二维数组,学了一维和二维后,很好类推到三维。

不同维度的数组之间,从外形上的本质区别是一维数组使用 1 层中括号表示;

二维数组使用 2 层中括号表示;

三维数组使用 3 层中括号表示。

有些函数需要传入数组的形状参数,不同维度数组的形状参数为一维数组的形状参数形如: x  (x,)

二维数组的形状参数形如: (x,y) ;三维数组的形状参数形如: (x,y,z)

现在以同一个序列进行举例

当数组有 1 层中括号,如[1 2 3],则其为一维数组,其形状是 3 或 (3,) ;当数组有 2 层中括号,如[[1 2 3]],则其为二维数组,其形状是 (1,3) ;

当数组有 3 层中括号,如[[[1 2 3]]],则其为三维数组,其形状是 (1,1,3) ; 这里用后面要讲的 np.ones( ) 函数进行演示,只因其刚好需要传入形状参数。

In [1] :

import numpy as np

In [2] :

arr1 = np.ones(3) # 传入形状 3

print(arr1) # 造出一维数组

[1. 1. 1.]

In [3] :

arr2 = np.ones((1,3)) # 传入形状(1,3)

print(arr2) # 造出二维数组

[[1. 1. 1.]]

In [4] :

arr3 = np.ones((1,1,3)) # 传入形状(1,1,3)

print(arr3) # 造出三维数组

[[[1. 1. 1.]]]

同时,我们还可以使用数组的 .shape 属性查看 arr1 和 arr2 的形状。

In [5] :

print( arr1.shape )

(3,)

In [6] :

print( arr2.shape )

(1, 3)

In [7] :

print( arr3.shape )

(1, 1, 3)

大家可以随时留意一下数组的维度(通过中括号的数量),后面有些函数(比如数组的拼接函数)需要两个数组是同维度的。

不同维度数组之间的转换

一维数组转二维数组,还是二维数组转一维数组,均要使用的是数组的重塑方法 .reshape( ) ,该方法需要传入重塑后的形状(shape)参数。

这个方法神奇的是,给定了其他维度的数值,剩下一个维度可以填-1,让它自己去计算。比如把一个 5 行 6 列的矩阵重塑为 3 行 10 列的矩阵,当列的参数

10 告诉它,行的参数直接可以用-1 来替代,它会自己去用 30 除以 10 来计算。首先,演示将一维数组升级为二维数组。

In [1] :

import numpy as np

In [2] :

# 创建一维数组

arr1 = np.arange(10)

print(arr1)

[0 1 2 3 4 5 6 7 8 9]

In [3] :

# 升级为二维数组

arr2 = arr1.reshape( (1,-1) )

print(arr2)

[[0 1 2 3 4 5 6 7 8 9]]

这里给.reshape( )传入的形状参数是(1,-1),正常情况下我们都肯定是(1,10),这里(1,-1)的含义是:行的参数是 1 行,列的参数-1 自己去除着算吧。

接着,演示将二维数组降级为一维数组。

In [1] :

import numpy as np

In [2] :

# 创建二维数组

arr2 = np.arange(10).reshape(2,5)

print(arr2)

[[0 1 2 3 4]

[5 6 7 8 9]]

In [3] :

# 降级为一维数组

arr1 = arr2.reshape( -1 )

print(arr1)

[0 1 2 3 4 5 6 7 8 9]

这里给.reshape( )传入的形状参数是 -1 ,正常情况应该是 10,这里-1 的含义是:反正是一维数组,形状直接自己去算吧。

现规定,本讲义中,将一维数组称为向量,二维数组称为矩阵。

二、数组的创

创建指定数

当明确知道数组每一个元素的具体数值时,可以使用 np.array( ) 函数,将

Python 列表转化为 NumPy 数组。

In [1] :

import numpy as np

In [2] :

#  创建一维数组——向

arr1 = np.array( [1,2,3] )

print(arr1)

[1 2 3]

In [3] :

#  创建二维数组——行矩

arr2 = np.array( [ [1,2,3] ] )

print(arr2)

[[1 2 3]]

In [4] :

#  创建二维数组——列矩

arr3 = np.array( [ [1],[2],[3] ] )

print(arr3)

[[1]

[2]

[3]]

In [5] :

#  创建二维数组——矩

arr4 = np.array( [ [1,2,3],[4,5,6] ] )

print(arr4)

[[1 2 3]

[4 5 6]]

创建递增数

递增数组使用 np.arange( ) 函数进行创建(arange 全称是 array_range)。

In [1] :

import numpy as np

In [2] :

# 递增数组

arr1 = np.arange(10) # 0 开始,到 10 之前结束

print(arr1)

[0 1 2 3 4 5 6 7 8 9]

In [3] :

# 递增数组

arr2 = np.arange(10,20) # 10 开始,到 20 之前结束

print(arr2)

[10 11 12 13 14 15 16 17 18 19]

In [4] :

# 递增数组

arr3 = np.arange(1,21,2) # 1 开始,到 21 之前结束,步长为 2

print(arr3)

[1 3 5 7 9 11 13 15 17 19]

​​​​​​​创建同值数

需要创建同值数组时,使用 np.zeros( ) 函数以及 np.ones( ) 函数,如示例。

In [1] :

import numpy as np

In [2] :

# 0 数组

arr1 = np.zeros( 3 ) # 形状为 3 的向量

print(arr1)

[0. 0. 0.]

In [3] :

# 1 数组

arr2 = np.ones( (1,3) ) # 形状为(1,3)的矩阵

print(arr2)

[[1. 1. 1.]]

In [4] :

# 3.14 数组

arr3 = 3.14 * np.ones( (2,3) ) # 形状为(2,3)的矩阵

print(arr3)

[[3.14 3.14 3.14]

[3.14 3.14 3.14]]

示例中隐藏了一个细节——两个函数输出的并不是整数型的数组,这可能是为了避免插进去的浮点数被截断,所以将其设定为浮点型数组。

创建随机数

有时需要创建随机数组,那么可以使用 np.random 系列函数,如示例所示。

In [1] :

import numpy as np

In [2] :

# 0-1 均匀分布的浮点型随机数组

arr1 = np.random.random( 5 ) # 形状为 5 的向量

print( arr1 )

[0.59699399 0.89113584 0.00695752 0.49089431 0.32050609]

In [2]中,如果想创建 60-100 范围内均匀分布的 3 行 3 列随机数组,可输入 (100-60)*np.random.random( (3,3) ) + 60

In [3] :

# 整数型随机数组

arr2 = np.random.randint( 10,100,(1,15) ) # 形状为(1,15)的矩阵

print( arr2 )

[[17 65 54 48 82 57 52 26 28 27 53 36 61 92 13]]

In [3]中,该函数需要额外输入范围参数,本例中范围是 10-100。

In [4] :

# 服从正态分布的随机数组

arr3 = np.random.normal( 0,1,(2,3) ) # 形状为(2,3)的二维矩阵

print( arr3 )

[[-0.43163964 -1.56817412 0.5460523 ]

[-2.93093358 0.42577899 -1.69842077]]

In [4]中,该函数需要额外输入正态参数,本例中均值为 0、标准差为 1,这种情况可直接使用 np.random.randn( )函数,只需要传入形状参数即可。

三、数组的索

前面我们规定,将一维数组称为向量,将二维数组称为矩阵。

访问数组元

与 Python 列表一致,访问 NumPy 数组元素时使用中括号,索引由 0 开始。

访问向量

In [1] :

import numpy

as

np

In [2] :

# 创建向量

arr1 = np.arange( 1,10 )

print( arr1 )

[1 2 3 4 5 6 7 8 9]

In [3] :

# 访问元素

print( arr1[3] )

print( arr1[-1] )

# 正着访问

# 倒着访问

4

9

In [4] :

# 修改数组元素

arr1[3= 100;

print( arr1 )

[1 2 3 100 5 6 7 8 9]

访问矩阵

In [5] :

# 创建矩阵

arr2 = np.array( [ [1,2,3],[4,5,6] ] )

print(arr2)

[[1 2 3]

[4 5 6]]

In [6] :

# 访问元素

print( arr2[0,2] )

print( arr2[1,-2] )

3

5

In [7] :

# 修改元素

arr2[1,1= 100.9

print( arr2 )

[[ 1 2 3]

[ 4 100 6]]

In [7]中,浮点数 100.9 插入到整数型数组时被截断了。

​​​​​​​花式索

花式索引(Fancy indexing)又名“花哨的索引”,UP 认为不应该用“花哨”来形容,这里的 Fancy 应取“华丽的、巧妙的、奢华的、时髦的”之义。

上一小节访问单个元素时,向量用 arr1[x],矩阵用 arr2[x,y]。逗号在矩阵里用于区分行与列,这一小节,逗号新增一个功能,且不会与矩阵里的逗号混淆。普通索引用一层中括号,花式索引用两层中括号。

向量的花式索引

In [1] :

import numpy as np

In [2] :

# 创建向量

arr1 = np.arange(0,90,10)

print(arr1)

[ 0 10 20 30 40 50 60 70 80]

In [3] :

# 花式索引

print( arr1[ [0,2] ] )

[0 20]

矩阵的花式索引

In [4] :

# 创建矩阵

arr2 = np.arange(1,17).reshape(4,4)

print(arr2)

[[ 1  2  3  4]

[ 5  6  7  8]

[ 9 10 11 12]

[13 14 15 16]]

In [5] :

# 花式索引

print( arr2[ [0,1] , [0,1] ] )

print( arr2[ [0,1,2] , [2,1,0] ] )

[1 6]

[3 6 9]

In [6] :

# 修改数组元素

arr2[ [0,1,2,3] , [3,2,1,0] ] = 100

print(arr2)

[[ 1 2 3 100]

[ 5 6 100 8]

[ 9 100  11  12]

[100  14  15  16]]

根据以上实例,花式索引输出的仍然是一个向量。

表 3-1 普通索引与花式索引的区别

索引方式

向量

矩阵

普通索引

arr1[ x1 ]

arr2[ x1 , y1 ]

花式索引

arr1[ [x1,x2,…,xn] ]

arr2[ [x1,x2,…,xn] , [y1,y2,…,yn] ]

​​​​​​​访问数组切

向量的切片

向量与列表切片的操作完全一致。

In [1] :

import numpy as np arr1 = np.arange(10)

当明确知道从第 x 个元素切到第 y 个元素,如示例所示。

In [2] :

print( arr1 )

print( arr1[ 1 : 4 ] ) #  从索引[1]开始,切到索引[4]之前

print( arr1[ 1 : ] ) # 从索引[1]开始,切到结尾

print( arr1[ : 4 ] ) # 从数组开头开始,切到索引[4]之前

[0 1 2 3 4 5 6 7 8 9]

[1 2 3]

[1 2 3 4 5 6 7 8 9]

[0 1 2 3]

当明确切除数组的开头与结尾,如示例所示。

In [3] :

print( arr1 )

print( arr1[ 2 : -2 ] ) # 切除开头 2 个和结尾 2 个

print( arr1[ 2 : ] ) # 切除开头 2 个

print( arr1[ : -2 ] ) # 切除结尾 2 个

[0 1 2 3 4 5 6 7 8 9]

[2 3 4 5 6 7]

[2 3 4 5 6 7 8 9]

[0 1 2 3 4 5 6 7]

当明确隔几个元素采样一次时,示例如下。

In [4] :

print( arr1 )

print( arr1[ : : 2 ] ) # 每 2 个元素采样一次

print( arr1[ : : 3 ] ) # 每 3 个元素采样一次

print( arr1[ 1 : -1 : 2 ] ) # 切除一头一尾后,每 2 个元素采样一次

[0 1 2 3 4 5 6 7 8 9]

[0 2 4 6 8]

[0 3 6 9]

[1 3 5 7]

矩阵的切片

In [1] :

import numpy as np

In [2] :

arr2 = np.arange(1,21).reshape(4,5) print( arr2 )

[[  1  2  3  4  5]

[ 6  7  8  9 10]

[11 12 13 14 15]

[16 17 18 19 20]]

In [3] :

print( arr2[ 1:3 , 1:-1 ] ) # 矩阵切片初体验

[[  7  8  9]

[12 13 14]]

In [4] :

print( arr2[ ::3 , ::2 ] ) # 跳跃采样

[[  1  3  5]

[16 18 20]]

提取矩阵的行

基于矩阵的切片功能,我们可以提取其部分行,如示例所示。

In [1] :

import numpy as np

In [2] :

arr3 = np.arange(1,21).reshape(4,5) print( arr3 )

[[  1  2  3  4  5]

[ 6  7  8  9 10]

[11 12 13 14 15]

[16 17 18 19 20]]

In [3] :

print( arr3[ 2 , : ] ) # 提取第 2 行

[11 12 13 14 15]

In [4] :

print( arr3[ 1:3 , : ] ) # 提取 1 至 2 行

[[ 6  7  8  9 10]

[11 12 13 14 15]]

考虑代码的简洁,当提取矩阵的某几行时可简写(但提取列的时候不可简写)。

In [5] :

print( arr3[ 2 , : ] ) # 规范的提取行

print( arr3[2] ) # 简便的提取行

[11 12 13 14 15]

[11 12 13 14 15]

所以,有时你可能看到诸如 arr[1][2] 这样的语法,不必吃惊,其实这只是先提取了第 1 行,再提取该行中第 2 个元素。提一句,UP 并不推荐这样的写法。

提取矩阵的列

基于矩阵的切片功能,我们可以提取其部分列,如示例所示。

In [1] :

import numpy as np

In [2] :

arr4 = np.arange(1,21).reshape(4,5) print( arr4 )

[[  1  2  3  4  5]

[ 6  7  8  9 10]

[11 12 13 14 15]

[16 17 18 19 20]]

In [3] :

print( arr4[ : , 2 ] ) # 提取第 2 列(注意,输出的是向量

[3 8 13 18]

In [4] :

print( arr4[ : , 1:3 ] ) # 提取 1 至 2 列

[[  2  3]

[ 7  8]

[12 13]

[17 18]]

值得注意的是,提取某一个单独的列时,出来的结果是一个向量。其实这么做只是为了省空间,我们知道,列矩阵必须用两层中括号来存储,而形状为 1000

的向量,自然比形状为(1000,1)的列矩阵更省空间(节约了 1000 对括号)。如果你真的想要提取一个列矩阵出来,示例如下。

In [1] :

import numpy as np

In [2] :

arr5 = np.arange(1,16).reshape(3,5) print( arr5 )

[[  1  2  3  4  5]

[ 6  7  8  9 10]

[11 12 13 14 15]]

In [3] :

cut = arr5[ : , 2 ] # 提取第 2 列为向量

print( cut )

[3 8 13]

In [4] :

cut = cut.reshape( (-1,1) ) # 升级为列矩阵

print(cut)

[[ 3]

[ 8]

[13]]

​​​​​​​数组切仅是视

与 Python 列表和 Matlab 不同,NumPy 数组的切片仅仅是原数组的一个视图。换言之,NumPy 切片并不会创建新的变量,示例如下。

In [1] :

import numpy as np

In [2] :

arr = np.arange(10) # 创建原数组 arr

print(arr)

[0 1 2 3 4 5 6 7 8 9]

In [3] :

cut = arr[ : 3 ] # 创建 arr 的切片 cut

print(cut)

[0 1 2]

In [4] :

cut[0] = 100 # 对切片的数值进行修改

print(cut)

[100 1 2]

In [5] :

print(arr) # 原数组也被修改

[100 1 2 3 4 5 6 7 8 9]

习惯 Matlab 的用户可能无法理解,但其实这正是 NumPy 的精妙之处。试想一下,一个几百万条数据的数组,每次切片时都创建一个新变量,势必造成大量的内存浪费。因此,NumPy 的切片被设计为原数组的视图是极好的。

深度学习中为节省内存,将多次使用 arr[:] = <表达式> 来替代 arr = <表达式>。

备份切片为新变量

如果真的需要为切片创建新变量(这种情况很稀少),使用 .copy( ) 方法。

In [1] :

import numpy as np

In [2] :

arr = np.arange(10) # 创建一个 0 到 10 的向量 arr

print(arr)

[0 1 2 3 4 5 6 7 8 9]

In [3] :

copy = arr[ : 3 ] .copy() # 创建 arr 的拷贝切片

print(copy)

[0 1 2]

In [4] :

copy [0] = 100 # 对拷贝切片的数值进行修改

print(copy)

[100 1 2]

In [5] :

print(arr) # 原数组不为所动

[0 1 2 3 4 5 6 7 8 9]

​​​​​​​数组赋值仅是绑

与 NumPy 数组的切片一样,NumPy 数组完整的赋值给另一个数组,也只是绑定。换言之,NumPy 数组之间的赋值并不会创建新的变量,示例如下。

In [1] :

import numpy as np

In [2] :

arr1 = np.arange(10) # 创建一个 0 到 10 的数组变量 arr

print(arr1)

[0 1 2 3 4 5 6 7 8 9]

In [3] :

arr2 = arr1 # 把数组 1 赋值给另一个数组 2

print(arr2)

[0 1 2 3 4 5 6 7 8 9]

In [4] :

arr2[0] = 100 # 修改数组 2

print(arr2)

[100 1 2 3 4 5 6 7 8 9]

In [5] :

print(arr1) # 原数组也被修改

[100 1 2 3 4 5 6 7 8 9]

此特性的出现仍然是为了节约空间,破局的方法仍然与前面相同。

复制数组为新变量

如果真的需要赋给一个新数组,使用 .copy( ) 方法。

In [1] :

import numpy as np

In [2] :

arr1 = np.arange(10) # 创建一个 0 到 10 的数组变量 arr

print(arr1)

[0 1 2 3 4 5 6 7 8 9]

In [3] :

arr2 = arr1.copy() # 把数组 1 的拷贝赋值给另一个数组 2

print(arr2)

[0 1 2 3 4 5 6 7 8 9]

In [4] :

arr2[0] = 100 # 修改数组 2

print(arr2)

[100 1 2 3 4 5 6 7 8 9]

In [5] :

print(arr1) # 查看数组 1

[0 1 2 3 4 5 6 7 8 9]

四、数组

数组的转

数组的转置方法为 .T,其只对矩阵有效,因此遇到向量要先将其转化为矩阵。

向量的转置

In [1] :

import numpy as np

In [2] :

arr1 = np.arange(1,4) # 创建向量

print(arr1)

[1 2 3]

In [3] :

arr2 = arr1.reshape( (1,-1) ) # 升级为矩阵

print(arr2)

[[1 2 3]]

In [4] :

arr3 = arr2.T # 行矩阵的转置

print(arr3)

[[1]

[2]

[3]]

矩阵的转置

行矩阵的转置刚演示了,列矩阵的转置如示例所示。

In [1] :

import numpy as np

In [2] :

arr1 = np.arange(3).reshape(3,1) # 创建列矩阵

print(arr1)

[[0]

[1]

[2]]

In [3] :

arr2 = arr1.T # 列矩阵的转置

print(arr2) # 结果为行矩阵

[[0 1 2]]

矩阵的转置如示例所示。

In [1] :

import numpy as np

In [2] :

arr1 = np.arange(4).reshape(2,2) # 创建矩阵

print(arr1)

[[0 1]

[2 3]]

In [3] :

arr2 = arr1.T # 矩阵的转置

print(arr2)

[[0 2]

[1 3]]

​​​​​​​数组的翻

数组的翻转方法有两个,一个是上下翻转的 np.flipud( ) ,表示 up-down;一个是左右翻转的 np.fliplr( ),表示 left-right。其中,向量只能使用 np.flipud( ),在数学中,向量并不是横着排的,而是竖着排的。

向量的翻转

In [1] :

import numpy as np

In [2] :

# 创建向量

arr1 = np.arange(10)

print( arr1 )

[0 1 2 3 4 5 6 7 8 9]

In [3] :

# 翻转向量

arr_ud = np.flipud(arr1)

print( arr_ud )

[9 8 7 6 5 4 3 2 1 0]

矩阵的翻转

In [1] :

import numpy as np

In [2] :

# 创建矩阵

arr2 = np.arange(1,21).reshape(4,5)

print( arr2 )

[[  1  2  3  4  5]

[ 6  7  8  9 10]

[11 12 13 14 15]

[16 17 18 19 20]]

In [3] :

# 左右翻转

arr_lr = np.fliplr(arr2)

print( arr_lr )

[[ 5  4  3  2  1]

[10  9  8  7  6]

[15 14 13 12 11]

[20 19 18 17 16]]

In [4] :

# 上下翻转

arr_ud = np.flipud(arr2)

print( arr_ud )

[[16 17 18 19 20]

[11 12 13 14 15]

[ 6  7  8  9 10]

[ 1  2  3  4  5]]

​​​​​​​数组的重

想要重塑数组的形状,需要用到 .reshape( ) 方法。

前面说过,给定了其他维度的数值,剩下一个维度可以填-1,让它自己去计算。比如把一个 5 行 6 列的矩阵重塑为 3 行 10 列的矩阵,当列的参数 10 告诉

它,行的参数直接可以用-1 来替代,它会自己去用 30 除以 10 来计算。

向量的变形

In [1] :

import numpy as np

In [2] :

arr1 = np.arange(1,10) # 创建向量

print(arr1)

[1 2 3 4 5 6 7 8 9]

In [3] :

arr2 = arr1.reshape(3,3) # 变形为矩阵

print(arr2)

[[1 2 3]

[4 5 6]

[7 8 9]]

矩阵的变形

In [1] :

import numpy as np

In [2] :

arr1 = np.array( [ [1,2,3],[4,5,6] ] ) # 创建矩阵

print(arr1)

[[1 2 3]

[4 5 6]]

In [3] :

arr2 = arr1.reshape(6) # 变形为向量

print(arr2)

[1 2 3 4 5 6]

In [4] :

arr3 = arr1.reshape(1,6) # 变形为矩阵

print(arr3)

[[1 2 3 4 5 6]]

​​​​​​​数组的拼

向量的拼接

两个向量拼接,将得到一个新的加长版向量。

In [1] :

import numpy as np

In [2] :

# 创建向量 1

arr1 = np.array( [1,2,3] )

print(arr1)

[1 2 3]

In [3] :

# 创建向量 2

arr2 = np.array( [4,5,6] )

print(arr2)

[4 5 6]

In [4] :

# 拼接

arr3 = np.concatenate( [arr1,arr2] )

print(arr3)

[1 2 3 4 5 6]

矩阵的拼接

两个矩阵可以按不同的维度进行拼接,但拼接时必须注意维度的吻合。

In [1] :

import numpy as np

In [2] :

# 创建数组 1

arr1 = np.array( [[1,2,3],[ 4,5,6]] )

print(arr1)

[[1 2 3]

[4 5 6]]

In [3] :

# 创建数组 2

arr2 = np.array( [[7,8,9],[10,11,12]] )

print(arr2)

[[ 7  8  9]

[10 11 12]]

In [4] :

# 按第一个维度(行)拼接

arr3 = np.concatenate( [arr1,arr2] ) # 默认参数 axis=0

print(arr3)

[[ 1  2  3]

[ 4  5  6]

[ 7  8  9]

[10 11 12]]

In [5] :

# 按第二个维度(列)拼接

arr4 = np.concatenate( [arr1,arr2] ,axis=1 )

print(arr4)

[[ 1  2  3  7  8  9]

[ 4  5  6 10 11 12]]

最后要说明的是,向量和矩阵不能进行拼接,必须先把向量升级为矩阵。

​​​​​​​数组的分

向量的分裂

向量分裂,将得到若干个更短的向量。

In [1] :

import numpy as np

In [2] :

# 创建向量

arr = np.arange(10,100,10)

print(arr)

[10 20 30 40 50 60 70 80 90]

In [3] :

# 分裂数组

arr1,arr2,arr3 = np.split( arr , [2,8] )

print(arr1) print(arr2) print(arr3)

[10 20]

[30 40 50 60 70 80]

[90]

np.split( )函数中,给出的第二个参数[2,8]表示在索引[2]和索引[8]的位置截断。

矩阵的分裂

矩阵的分裂同样可以按不同的维度进行,分裂出来的均为矩阵。

In [1] :

import numpy as np

In [2] :

# 创建矩阵

arr = np.arange(1,9).reshape(2,4)

print(arr)

[[1 2 3 4]

[5 6 7 8]]

In [3] :

# 按第一个维度(行)分裂

arr1,arr2 = np.split(arr,[1]) # 默认参数 axis=0

print(arr1 , '\n\n' , arr2) # 注意输出的是矩阵

[[1 2 3 4]]

[[5 6 7 8]]

In [4] :

# 按第二个维度(列)分裂

arr1,arr2,arr3 = np.split( arr , [1,3] , axis=1 )

print( arr1 , '\n\n' , arr2 , '\n\n' , arr3 )

[[1]

[5]]

[[2 3]

[6 7]]

[[4]

[8]]

五、数组的运

数组与系数之的运

Python 基础中,常用的运算符如表 5-1 所示,NumPy 的运算符与之相同。

表 5-1 常见的运算符

运算符

含义

输入

输出

+-*/

加、减、乘、除

1 * 2 + 3 / 4

2.75

**

2 ** 4

16

( )

修正运算次序

1 * 2 + 3 ) / 4

1.25

//

取整

28 // 5

5

%

取余

28 % 5

3

这里仅以矩阵为例,向量与系数的操作与之相同。

In [1] :

import numpy as np

In [2] :

# 创建矩阵

arr = np.arange(1,9).reshape(2,4)

print( arr )

[[1 2 3 4]

[5 6 7 8]]

In [3] :

print( arr + 10 ) # 加法

[[11 12 13 14]

[15 16 17 18]]

In [4] :

print( arr - 10 ) # 减法

[[-9 -8 -7 -6]

[-5 -4 -3 -2]]

In [5] :

print( arr * 10 ) # 乘法

[[10 20 30 40]

[50 60 70 80]]

In [6] :

print( arr / 10 ) # 除法

[[0.1 0.2 0.3 0.4]

[0.5 0.6 0.7 0.8]]

In [7] :

print( arr ** 2) # 平方

[[ 1  4  9 16]

[25 36 49 64]]

In [8] :

print( arr // 6) # 取整

[[0 0 0 0]

[0 1 1 1]]

In [9] :

print( arr % 6) # 取余

[[1 2 3 4]

[5 0 1 2]]

​​​​​​​数组与数组之的运

同维度数组间的运算即对应元素之间的运算,这里仅以矩阵为例,向量与向量的操作与之相同。

In [1] :

import numpy as np

In [2] :

# 创建矩阵

arr1 = np.arange(-1,-9,-1).reshape(2,4)

arr2 = -arr1 print( arr1 )

print( arr2 )

[[-1 -2 -3 -4]

[-5 -6 -7 -8]]

[[1 2 3 4]

[5 6 7 8]]

In [3] :

print( arr1 + arr2 ) # 加法

[[0 0 0 0]

[0 0 0 0]]

In [4] :

print( arr1 - arr2 ) # 减法

[[  -2  -4  -6  -8]

[-10 -12 -14 -16]]

In [5] :

print( arr1 * arr2 ) # 乘法

[[ -1 -4 -9 -16]

[-25 -36 -49 -64]]

In [6] :

print( arr1 / arr2 ) # 除法

[[-1. -1. -1. -1.]

[-1. -1. -1. -1.]]

In [7] :

print( arr1 ** arr2) # 幂方

[[ -1 4 -27 256]

[ -3125 46656 -823543 16777216]]

上述 In [5]中,乘法是遵循对应元素相乘的,你可以称之为“逐元素乘积”。那么如何实现线性代数中的“矩阵级乘法”呢?6.1 会介绍到相关函数。

​​​​​​​广

是同形状数组之间的逐元素运算,本节讲解不同形状的数组之间的运算。本课件仅讨论二维数组之内的情况,不同形状的数组之间的运算有以下规则:

  1. 如果是向量与矩阵之间做运算,向量自动升级为行矩阵;
  2. 如果某矩阵是行矩阵或列矩阵,则其被广播,以适配另一个矩阵的形状

向量被广播

当一个形状为(x,y)的矩阵与一个向量做运算时,要求该向量的形状必须为 y,运算时向量会自动升级成形状为(1,y)的行矩阵,该形状为(1,y)的行矩阵再自动被广播为形状为(x,y)的矩阵,这样就与另一个矩阵的形状适配了。

In [1] :

import numpy as np

In [2] :

# 向量

arr1 = np.array([-100,0,100])

print(arr1)

[-100 0 100]

In [3] :

# 矩阵

arr2 = np.random.random( (10,3) )

print(arr2)

[[0.60755301 0.47875215 0.70909527]

[0.12946037 0.78380689 0.7771824 ]

[0.2658308 0.34287368 0.21176781]

[0.93920876 0.73860266 0.32531675]

[0.92474339 0.97997977 0.98410076]

[0.52791609 0.17325381 0.04736612]

[0.8543378 0.707902 0.36518268]

[0.72053659 0.71830332 0.12972364]

[0.86540524 0.95537187 0.66062319]

[0.46449401 0.88824093 0.77800761]]

In [4] :

# 广播

print(arr1*arr2)

[[-60.75530134 0. 70.90952713]

[-12.94603684 0. 77.71823953]

[-26.58307957 0. 21.17678114]

[-93.92087564 0. 32.53167491]

[-92.47433933 0. 98.41007632]

[-52.7916095 0. 4.73661185]

[-85.43377956 0. 36.51826765]

[-72.05365932 0. 12.97236352]

[-86.54052368 0. 66.06231879]

[-46.44940114 0. 77.80076055]]

列矩阵被广播

当一个形状为(x,y)的矩阵与一个列矩阵做运算时,要求该列矩阵的形状必须为(x,1),该形状为(x,1)的列矩阵再自动被广播为形状为(x,y)的矩阵,这样就与另一个矩阵的形状适配了。

In [1] :

import numpy as np

In [2] :

# 列矩阵

arr1 = np.arange(3).reshape(3,1)

print(arr1)

[[0]

[1]

[2]]

In [3] :

# 矩阵

arr2 = np.ones( (3,5) )

print(arr2)

[[1. 1. 1. 1. 1.]

[1. 1. 1. 1. 1.]

[1. 1. 1. 1. 1.]]

In [4] :

# 广播

print(arr1*arr2)

[[0. 0. 0. 0. 0.]

[1. 1. 1. 1. 1.]

[2. 2. 2. 2. 2.]]

行矩阵与列矩阵同时被广播

当一个形状为(1,y)的行矩阵与一个形状为(x,1) 的列矩阵做运算时,这俩矩阵都会被自动广播为形状为(x,y)的矩阵,这样就互相适配了。

In [1] :

import numpy as np

In [2] :

# 向量

arr1 = np.arange(3)

print(arr1)

[0 1 2]

In [3] :

# 列矩阵

arr2 = np.arange(3).reshape(3,1)

print(arr2)

[[0]

[1]

[2]]

In [4] :

# 广播

print(arr1*arr2)

[[0 0 0]

[0 1 2]

[0 2 4]]

六、数组的函

矩阵乘

  1. 第五章中的乘法都是“逐元素相乘”,这里介绍线性代数中的矩阵乘积,本节只需要使用 np.dot( ) 函数。
  2. 当矩阵乘积中混有向量时,根据需求,其可充当行矩阵,也可充当列矩阵,但混有向量时输出结果必为向量。

向量与向量的乘积

设两个向量的形状按前后顺序分别是  5 以及 5 。从矩阵乘法的角度,有

(1, 5)´(5,1) = (1,1) ,因此输出的应该是形状为 1 的向量。

In [1] :

import numpy as np

In [2] :

# 创建向量

arr1 = np.arange(5)

arr2 = np.arange(5) print(arr1) print(arr2)

[0 1 2 3 4]

[0 1 2 3 4]

In [3] :

# 矩阵乘积

print( np.dot(arr1,arr2) )

30

向量与矩阵的乘积

设向量的形状是 5 , 矩阵的形状是 (5,3) 。从矩阵乘法的角度,有

(1, 5)´(5, 3) = (1, 3) ,因此输出的应该是形状为 3 的向量。

In [1] :

import numpy as np

In [2] :

# 创建数组

arr1 = np.arange(5)

arr2 = np.arange(15).reshape(5,3) print(arr1)

print(arr2)

[0 1 2 3 4]

[[ 0  1  2]

[ 3  4  5]

[ 6  7  8]

[ 9 10 11]

[12 13 14]]

In [3] :

# 矩阵乘积

print( np.dot(arr1,arr2) )

[90 100 110]

矩阵与向量的乘积

设矩阵的形状是 (3,5) , 向量的形状是 5 。从矩阵乘法的角度, 有

(3, 5)´(5,1) = (3,1) ,因此输出的应该是形状为 3 的向量。

In [1] :

import numpy as np

In [2] :

# 创建数组

arr1 = np.arange(15).reshape(3,5)

arr2 = np.arange(5) print(arr1)

print(arr2)

[[  0  1  2  3  4]

[ 5  6  7  8  9]

[10 11 12 13 14]]

[0 1 2 3 4]

In [3] :

# 矩阵乘积

print( np.dot(arr1,arr2) )

[ 30  80 130]

矩阵与矩阵的乘积

设两个矩阵的形状按前后顺序分别是 (5,2) 以及 (2,8) 。从矩阵乘法的角度,有(5, 2)´(2,8) = (5,8) ,因此输出的应该是形状为 (5,8) 的矩阵。

In [1] :

import numpy as np

In [2] :

# 创建数组 1

arr1 = np.arange(10).reshape(5,2)

print(arr1)

[[0 1]

[2 3]

[4 5]

[6 7]

[8 9]]

In [3] :

# 创建数组 2

arr2 = np.arange(16).reshape(2,8)

print(arr2)

[[ 0  1  2  3  4  5  6  7]

[ 8  9 10 11 12 13 14 15]]

In [4] :

# 矩阵乘积

print( np.dot(arr1,arr2) )

[[ 8 9  10  11  12  13  14  15]

[ 24  29  34  39  44  49  54  59]

[ 40  49  58  67  76  85  94 103]

[ 56  69  82  95 108 121 134 147]

[ 72  89 106 123 140 157 174 191]]

​​​​​​​数学函

NumPy 设计了很多数学函数,这里列举其中最重要、最常见的几个。

In [1] :

import numpy as np

In [2] :

# 绝对值函数

arr_v = np.array( [-10010] )

abs_v = np.abs(arr_v) print( '原数组是:' , arr_v )

print( '绝对值是:' , abs_v )

原数组是: [-10 0 10]

绝对值是: [10 0 10]

In [3] :

# 三角函数

theta = np.arange(3* np.pi / 2

sin_v = np.sin(theta) cos_v = np.cos(theta) tan_v = np.tan(theta)

print( '原数组是:' , theta ) print( '正弦值是:' , sin_v ) print( '余弦值是:' , cos_v )

print( '正切值是:' , tan_v )

原数组是: [0. 1.57079633 3.14159265]

正弦值是: [0.0000000e+00 1.0000000e+00 1.2246468e-16]

余弦值是: [ 1.000000e+00 6.123234e-17 -1.000000e+00]

正切值是: [ 0.00000000e+00 1.63312394e+16 -1.22464680e-16]

In [4] :

# 指数函数

= np.arange(1,4)

print'x =' , x )

print( 'e^x =' , np.exp(x) ) print( '2^x  =' , 2**x )

print'10^x = ' , 10**x )

x = [1 2 3]

e^x = [ 2.71828183 7.3890561 20.08553692]

2^x = [2 4 8]

10^x = [ 10 100 1000]

In [5] :

# 对数函数

= np.array( [1,10,100,1000] )

print'x =' , x )

print'ln(x) =' , np.log(x) )

print'log2(x) =' , np.log(x) / np.log(2) )

print'log10(x) =' , np.log(x) / np.log(10) )

x = [ 1 10 100 1000]

ln(x) = [0. 2.30258509 4.60517019 6.90775528]

log2(x) = [0. 3.32192809 6.64385619 9.96578428]

log10(x) = [0. 1. 2. 3.]

​​​​​​​聚合函

聚合很有用,这里用矩阵演示。向量与之一致,但没有 axis 参数。以下在注释中介绍了 6 个最重要的聚合函数,其用法完全一致,仅演示其中 3 个。

In [1] :

import numpy as np

In [2] :

# 最大值函数 np.max( )与最小值函数 np.min( )

arr = np.random.random((2,3))

print( arr )

print( '按维度一求最大值:' , np.max(arr,axis=0) ) print( '按维度二求最大值:' , np.max(arr,axis=1) )

print( '整体求最大值:' , np.max(arr) )

[[0.54312818 0.57067295 0.11898755]

[0.85857494 0.33915753 0.4742594 ]]

按维度一求最大值: [0.85857494 0.57067295 0.4742594 ]

按维度二求最大值: [0.57067295 0.85857494]

整体求最大值: 0.8585749445359108

In [3] :

# 求和函数 np.sum( )与求积函数 np.prod( )

arr = np.arange(10).reshape(2,5)

print( arr )

print( '按维度一求和:' , np.sum(arr,axis=0) ) print( '按维度二求和:' , np.sum(arr,axis=1) )

print( '整体求和:' , np.sum(arr) )

[[0 1 2 3 4]

[5 6 7 8 9]]

按维度一求和: [ 5 7 9 11 13]

按维度二求和: [10 35]

整体求和: 45

In [4] :

# 均值函数 np.mean( )与标准差函数 np.std( )

arr = np.arange(10).reshape(2,5)

print( arr )

print( '按维度一求平均:' , np.mean(arr,axis=0) ) print( '按维度二求平均:' , np.mean(arr,axis=1) )

print( '整体求平均:' , np.mean(arr) )

[[0 1 2 3 4]

[5 6 7 8 9]]

按维度一求平均: [2.5 3.5 4.5 5.5 6.5]

按维度二求平均: [2. 7.]

整体求平均: 4.5

  1. 当 axis=0 时,最终结果与每一行的元素个数一致;当 axis=1 时,最终结果与每一列的元素个数一致。
  2. 考虑到大型数组难免有缺失值,以上聚合函数碰到缺失值时会报错,因此出现了聚合函数的安全版本,即计算时忽略缺失值:np.nansum( )、 np.nanprod( ) 、np.nanmean( )、np.nanstd( )、np.nanmax( )、np.nanmin( )。

七、布尔型数

除了整数型数组和浮点型数组,还有一种有用的数组类型——布尔型数组。

创建布尔型数

由于 NumPy 的主要数据类型是整数型数组或浮点型数组,因此布尔型数组的产生离不开:大于>、大于等于>=、等于==、不等号!=、小于<、小于等于<=

首先,我们将数组与系数作比较,以产生布尔型数组,示例如下。

In [1] :

import numpy as np

In [2] :

# 创建数组

arr = np.arange(1,7).reshape(2,3)

print(arr)

[[1 2 3]

[4 5 6]]

In [3] :

# 数组与数字作比较

print( arr >= 4 )

[[False  False False] [True True True]]

其次,我们将同维数组作比较,以产生布尔型数组,示例如下。

In [1] :

import numpy as np

In [2] :

# 创建同维数组

arr1 = np.arange(1,6)

arr2 = np.flipud(arr1) print(arr1) print(arr2)

[1 2 3 4 5]

[5 4 3 2 1]

In [3] :

# 同维度数组作比较

print( arr1 > arr2)

[False False False True True]

最后,还可以同时比较多个条件。Python 基础里,同时检查多个条件使用的与、或、非是 andornot。但 NumPy 中使用的与、或、非是 & | ~ 

In [1] :

import numpy as np

In [2] :

# 创建数组

arr = np.arange(1,10)

print(arr)

[1 2 3 4 5 6 7 8 9]

In [3] :

# 多个条件

print( (arr < 4| (arr > 6) )

[ True True True False False False True True True]

​​​​​​​布尔型数组True 的数

有三个关于 Ture 数量的有用函数,分别是 np.sum( )、np.any( )、np.all( )。

np.sum( )函数:统计布尔型数组里 True 的个数。示例如下。

In [1] :

import numpy as np

In [2] :

# 创建一个形状为 10000 的标准正态分布数

arr = np.random.normal( 0,1,10000 )

In [3] :

# 统计该分布中绝对值小于 1 的元素个数

num = np.sum( np.abs(arr) < 1 )

print( num )

6814

In [3]里,np.abs(arr) < 1 可以替换为 (arr>-1) & (arr<1) 。此外,最终统计的数量为 6814,其概率近似为 0.6827,这符合统计学中的 3σ 准则。

np.any( )函数:只要布尔型数组里含有一个及其以上的 True,就返回 True

In [1] :

import numpy as np

In [2] :

# 创建同维数组

arr1 = np.arange(1,10)

arr2 = np.flipud(arr1)

print(arr1) print(arr2)

[1 2 3 4 5 6 7 8 9]

[9 8 7 6 5 4 3 2 1]

In [3] :

# 统计这两个数组里是否有共同元素

print( np.any( arr1 == arr2 ) )

True

从结果来看,arr1 与 arr2 里含有共同元素,那就是 5

np.all( )函数:当布尔型数组里全是 True 时,才返回 True,示例如下。

In [1] :

import numpy as np

In [2] :

# 模拟英语六级的成绩,创建 100000 个样

arr = np.random.normal( 500,70,100000 )

In [3] :

# 判断是否所有考生的分数都高于 250

print( np.all( arr > 250 ) )

False

从结果来看,尽管 3σ 准则告诉我们有 99.73%的考生成绩高于 290 分(290通过500 - 3´70 计算得到),但仍然有最终成绩低于 250 分的裸考者。

​​​​​​​布尔型数组作

若一个普通数组和一个布尔型数组的维度相同,可以将布尔型数组作为普通数组的掩码,这样可以对普通数组中的元素作筛选。给出两个示例。

第一个示例,筛选出数组中大于、等于或小于某个数字的元素。

In [1] :

import numpy as np

In [2] :

# 创建数组

arr = np.arange(1,13).reshape(3,4)

print(arr)

[[ 1  2  3  4]

[ 5  6  7  8]

[ 9 10 11 12]]

In [3] :

# 数组与数字作比较

print( arr > 4 )

[[False False False False]

[ True True True True] [ True True True True]]

In [4] :

# 筛选出 arr > 4 的元素

print( arr[ arr > 4 ] )

[ 5  6  7  8  9 10 11 12]

注意,这个矩阵进行掩码操作后,退化为了向量。第二个示例,筛选出数组逐元素比较的结果。

In [1] :

import numpy as np

In [2] :

# 创建同维数组

arr1 = np.arange(1,10)

arr2 = np.flipud(arr1) print(arr1)

print(arr2)

[1 2 3 4 5 6 7 8 9]

[9 8 7 6 5 4 3 2 1]

In [3] :

# 同维度数组作比较

print( arr1 > arr2)

[False False False False False True True True True]

In [4] :

# 筛选出 arr1 > arr2 位置上的元素

print( arr1[ arr1 > arr2 ] )

print( arr2[ arr1 > arr2 ] )

[6 7 8 9]

[4 3 2 1]

​​​​​​​满足条件的元素所在位

现在我们来思考一种情况:假设一个很长的数组,我想知道满足某个条件的元素们所在的索引位置,此时使用 np.where( )函数。

In [1] :

import numpy as np

In [2] :

# 模拟英语六级成绩的随机数组,取 10000 个样本

arr = np.random.normal( 500,70,1000 )

In [3] :

# 找出六级成绩超过 650 的元素所在位置

print( np.where( arr > 650 ) )

(array([127, 129, 317, 342, 484, 490, 634, 658, 677, 755, 763, 819, 820,

853, 926, 932, 982], dtype=int64),)

In [4] :

# 找出六级成绩最高分的元素所在位置

print( np.where( arr == np.max(arr) ) )

(array([342], dtype=int64),)

np.where( )函数的输出看起来比较怪异,它是输出了一个元组。元组第一个元素是“满足条件的元素所在位置”;第二个元素是数组类型,可忽略掉。

八、从数组到张

位置

NumPy 的函数

PyTorch 的函数

用法区别

1.1 数据类型

.astype( )

.type( )

2.4 随机数组

np.random.random( )

torch.rand( )

2.4 随机数组

np.random.randint( )

torch.randint( )

不接纳一维张量

2.4 随机数组

np.random.normal( )

torch.normal( )

不接纳一维张量

2.4 随机数组

np.random.randn( )

torch.randn( )

3.4 数组切片

.copy( )

.clone( )

4.4 数组拼接

np.concatenate( )

torch.cat( )

4.5 数组分裂

np.split( )

torch.split( )

参数含义优化

6.1 矩阵乘积

np.dot( )

torch.matmul( )

6.1 矩阵乘积

np.dot(v,v)

torch.dot( )

6.1 矩阵乘积

np.dot(m,v)

torch.mv( )

6.1 矩阵乘积

np.dot(m,m)

torch.mm( )

6.2 数学函数

np.exp( )

torch.exp( )

必须传入张量

6.2 数学函数

np.log( )

torch.log( )

必须传入张量

6.3 聚合函数

np.mean( )

torch.mean( )

必须传入浮点型张量

6.3 聚合函数

np.std( )

torch.std( )

必须传入浮点型张量

http://www.dtcms.com/wzjs/192771.html

相关文章:

  • 做h5的网站页面怎样在百度上免费建网站
  • 长沙 网站设计 公司百度关键词搜索引擎
  • 昆明百度seo优化公司
  • 网站平台开发网站关键词优化网站推广
  • 可以自己制作头像的网站论坛推广网站
  • 涿州网站建设推广公众号软文范例100
  • 资阳房产网站建设谷歌网页
  • 做调查赚钱的网站又哪些网站开发框架
  • 医疗器械外贸网站建设网站seo排名优化工具
  • 网站建设技术网站电脑培训学校哪家最好
  • 四川网站建设培训班百度小说搜索风云榜总榜
  • 行业门户网站模板下载培训网
  • 网站的区别网络营销电子版教材
  • 政府网站谁做的国外网站推广
  • tp5企业网站开发视频开发一个平台需要多少钱
  • 物流如何做网站竞价托管公司排名
  • 网页视频制作软件网站快速优化排名排名
  • dreamweaver怎么做网站广东疫情最新通报
  • 优化网站的步骤案列下载百度网盘
  • 个人做网站能赚到钱吗网络营销的发展趋势
  • 新网站排名优化网站推广120种方法
  • 学校ftp服务器做网站网络广告文案范文
  • gta5显示网站建设中拉人头最暴利的app
  • 哪个网站反盗版做的最好seo实战培训学校
  • 山西教育平台网站建设怎样注册网站免费注册
  • 网站建设南京新闻发布会
  • 做电商讲师课程的网站女教师遭网课入侵直播录屏曝
  • 创一个网站怎样赚钱网络营销有哪些内容
  • 个人做负面网站犯法不排名sem优化软件
  • 东莞网站设计与制作公司西安网络优化培训机构公司