|
点击此处返回总目录
//1.菜鸟教程 http://www.runoob.com/numpy/numpy-array-manipulation.html
//2.《利用Python进行数据分析·第2版》及SeanCheney的翻译:https://www.jianshu.com/p/04d180d90a3f
一、Numpy库介绍
二、数组的属性
三、创建数组
四、索引和切片
五、矩阵运算
六、线性代数
七、通用函数
八、数组统计方法
九、排序
十、伪随机数生成
十一、数组重塑
十二、数组的合并和拆分
一、 Numpy库介绍
Numpy是Python的一个科学计算的库。
主要提供矩阵运算的功能,而矩阵运算在机器学习领域应用非常广泛。
Numpy一般与Scipy、matplotlib一起使用。
虽然python中的list已经提供了类似于矩阵的表示形式,不过numpy为我们提供了更多的函数。
1. 导入numpy
|
import numpy as np //当然也可以使用from numpy import *,但不建议这么做。numpy命名空间很大,包含许多函数,
其中一些名字与Python内置函数重名(比如min和max)。
|
二、数组的属性
NumPy的数组类称作ndarray,通常称作数组。注意numpy.array和标准Python库类中的array.array并不相同,后者只处理一维数组和提供少量的功能。ndarray类常用的属性有:
ndarray是一个通用的同构数据多维容器。同构的意思就是所有元素是相同类型的。
本文中“数组”、“Numpy数组”、“ndarray”,基本都是指同一个东西,即ndarray对象。
1. ndarray.ndim //数组的维度。二维数组为2,三维数组为3,以此类推。【例1】【例2】
2. ndarray.shape //数组的形状。返回一个表示各维度大小的元组。【例2】
3. ndarray.dtype //数组中元素的类型。【例3】
4. ndarray.size //数组元素个数。【例4】
5. ndarray.itemsize //每个元素所占的字节数。
例1:
|
import numpy as np
a=np.arange(10) //arrange()函数用于生成一个长度为10的数组:[0,1,2,3,4,5,6,7,8,9]。后面会讲。这里先用着。
b=a.reshape(2,5) //后面讲。
print(b.ndim) #2。二维数组,所以维度为2。
|
例2:
|
import numpy as np
a=np.arange(12)
b=a.reshape(2,3,2)
print(b.ndim) #3。三维数组。
print(b.shape) #(2,3,2)。返回的是表示各维度大小的元组。
|
例3:返回数组中元素的类型。
|
import numpy as np
a=np.arange(10)
print(a.dtype) #int32。
|
例4:
|
import numpy as np
a=np.arange(10)
print(a.size) #10。因为有10个元素。
|
三、创建数组
1.创建数组最简单的办法是array函数。它接收一切序列型的对象(包括其他数组),然后产生一个新的ndarray对象。
如果没有说明,array()会尝试为新建的这个数组推断出一个较为合适的数据类型。
array([1,2,3,4,5]) //使用列表生成一维数组。产生的数组类型为int32。【例1】
//注意:不要写成array(1,2,3,4,5)。
array((1.4,2.2,4.3)) //使用元组创建一维数组。产生的数据类型为float64。【例2】
嵌套序列将会被转换为一个多维数组
array([[1,2],[3,4],[5,6]]) //使用列表生成二维数组。序列包含序列转化为二维数组。【例3】
array([[[1,2]],[[3,4]],[[5,6]]]) //创建3*1*2的三维数组。序列包含序列包含序列转化为三维数组。【例4】
可以在创建时,指定数据类型
array([1,2,4],dtype=complex) //数据类型可以显示地指定。【例5】
array([1,2,3],dtype=float64)
2. zeros(6) //创建一个长度为6的,元素全为0的一维数组。默认创建数组类型是float64。【例6】
zeros((2,3)) //创建一个2行3列的二维数组,数组元素全为0。【例7】
3. ones(5) //创建一个长度为5的,元素全为1的一维数组。默认创建数组类型是float64。【例8】
ones((2,3)) //创建一个2行3列的二维数组,元素全为1。【例9】
4. empty(5) //创建一个长度5,为未初始化的一维数组。默认创建数组类型是float64。【例10】。注意返回的不是全零数组。
empty((2,3,4)) //创建一个未初始化的三维数组。【例11】
5. eye(4) //生成对角矩阵。默认创建数组类型是float64。【例12】
6. arange(5) //生成从0到5的数组。结果包含0,不包含5。即生成[0,1,2,3,4]。【例13】
arange(2,6) //生成从2到6的数组。即[2,3,4,5]。【例14】
arange(10,20,2) //生成10到20,步长为2的数组。即[10,12,14,16,18]。【例15】
arange(10).reshape(2,5) //改变形状成2行5列。【例16】。reshape()函数后面讲。
7. linspace(0,10,6) //从0到10(包含10),生成6个数的等差数列。即[0,2,4,6,8,10]。【例17】
8. X,Y=np.meshgrid(x,y) //生成网格数据。【例18】
9. x,y=np.mgrid[1:5:1,0:1:0.1] //生成网格数据。【例19】

例1:使用列表创建一维数组
|
import numpy as np
a=np.array([1,2,3,4,5]) #使用列表生成一维数组。
print(a) #[1 2 3 4 5]
print(a.dtype) #int32
|
例2:使用元组创建一维数组
|
import numpy as np
a=np.array((1.2,3.4,5.5)) #使用元组生成一维数组
print(a) #[1.2 3.4 5.5]
print(a.dtype) #float64
|
例3:使用序列创建二维数组
|
import numpy as np
a=np.array([(1,2),[3,4],[5,6]]) #序列里面包含序列。生成二维数组。通过这里例子可以看出,列表和元组可以混着用。
print(a)
print(a.shape)
|
运行结果:
[[1 2]
[3 4]
[5 6]]
(3, 2)
例4:使用序列创建三维数组
|
import numpy as np
a=np.array([[[1,2]],[[3,4]],[[5,6]]]) #3*1*2的三维数组
print(a)
print(a.shape)
|
运行结果:
[[[1 2]]
[[3 4]]
[[5 6]]]
(3, 1, 2)
例5:数据类型可以显示地指示。
|
import numpy as np
a=np.array([[1,2],[3,4]],dtype=complex)
print(a)
|
运行结果:
[[1.+0.j 2.+0.j]
[3.+0.j 4.+0.j]]
例6:
|
import numpy as np
a=np.zeros(6)
print(a)
print(a.dtype)
|
运行结果:
[0. 0. 0. 0. 0. 0.]
float64
例7:
|
import numpy as np
a=np.zeros((2,3))
print(a)
|
运行结果:
[[0. 0. 0.]
[0. 0. 0.]]
例8:
|
import numpy as np
a=np.ones(5)
print(a)
|
运行结果:
[1. 1. 1. 1. 1.]
例9:
|
import numpy as np
a=np.ones((3,4))
print(a)
|
运行结果:
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
例10:
|
import numpy as np
a=np.empty(5)
print(a)
|
运行结果:
[1. 1. 1. 1. 1.]
例11:
|
import numpy as np
a=np.empty((2,3,4))
print(a)
|
运行结果为三维数组:
[[[2.30217625e-316 7.36157812e-322 0.00000000e+000 0.00000000e+000]
[3.26787352e-312 1.16096346e-028 1.04857803e-142 1.16467185e-028]
[1.35188017e-153 1.65021835e-153 4.10115911e+223 1.96849090e-062]]
[[3.63472808e-043 2.69377482e+132 6.14126361e-071 8.48851774e+136]
[1.81152936e-152 1.13286318e-051 8.49306048e+136 1.81152937e-152]
[2.08976372e-032 6.16418248e-114 4.07177171e+223 1.35199672e-311]]]
例12:生成对角矩阵
|
import numpy as np
a=np.eye(4) //生成对角矩阵。
print(a)
|
运行结果:
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
例13:
|
import numpy as np
a=np.arange(10)
print(a)
|
运行结果:
[0 1 2 3 4 5 6 7 8 9]
例14:
|
import numpy as np
a=np.arange(2,6) //从2到6的数组。含2不含6。
print(a)
|
运行结果:
[2 3 4 5]
例15:
|
import numpy as np
a=np.arange(10,20,2) //从10到20的数组。步长为2。含10不含20。
print(a)
|
运行结果:
[10 12 14 16 18]
例16:
|
import numpy as np
a=np.arange(10).reshape(2,5)
print(a)
|
运行结果:
[[0 1 2 3 4]
[5 6 7 8 9]]
例17:
|
import numpy as np
a=np.linspace(0,10,6)
print(a) #[ 0. 2. 4. 6. 8. 10.]
|
例18:
|
import numpy as np
import matplotlib.pyplot as plt
m,n=5,3
x=np.linspace(0,1,m) #生成m个数据
y=np.linspace(0,1,n)
X,Y=np.meshgrid(x,y) #生成网格数据
print(x)
print(y)
print(X)
print(Y)
plt.plot(X,Y,'b.',linestyle='none')
plt.show()
|
运行结果:
[0. 0.25 0.5 0.75 1. ] #x
[0. 0.5 1. ] #y
[[0. 0.25 0.5 0.75 1. ] #X。三行五列。
[0. 0.25 0.5 0.75 1. ]
[0. 0.25 0.5 0.75 1. ]]
[[0. 0. 0. 0. 0. ] #Y。三行五列。
[0.5 0.5 0.5 0.5 0.5]
[1. 1. 1. 1. 1. ]]

例19:
|
import numpy as np
import matplotlib.pyplot as plt
xx,yy = np.mgrid[1:5:1,0:1:0.1]
print(xx)
print(yy)
plt.scatter(xx,yy,color='red')
plt.show()
|
运行结果:

四、索引和切片
#假设a=[0,1,2,3,4,5,6,7,8,9]。下面命令单独运行,没有关系。
a[5] #5。【例1】
a[5:8] #[5,6,7]。【例1】
a[1]=5 #将a的元素进行改变。a变为[0 5 2 3 4 5 6 7 8 9]。【例2】
a[5:8]=12 #将a的元素进行改变。a变为[ 0 1 2 3 4 12 12 12 8 9]。【例3】
#当将一个标量赋值给一个切片时,该值会自动传播(也就是附录中会讲到的“广播”)到整个选区。
#这种写法在python list中会报错。
a[:] =12 #将a的所有元素进行改变。【例4】。不能直接写为a=12。如果这样写,就相当于给a赋值12了。
b=a[5:8] #b=[5,6,7]。注意:如果再修改b的值,a的值也会改变。这是因为,数组切片是原始数组的视图。【例5】
#由于NumPy的设计目的是处理大数据,所以你可以想象一下,假如NumPy坚持要将数据复制来复制去的 话会产生何等的性能和内存问题。所以这样设计。这个地方跟python的切片不同。
b=a[5:8].copy() #如果想要得到的是ndarray切片的一份副本而非视图,就需要明确地进行复制操作。【例6】
#假设a=[[1,2,3,4],
[5,6,7,8]]
a[1] #[5 6 7 8]。在二维数组中,各索引位置上的元素不再是标量而是一维数组。【例7】
a[1][2] 或 a[1,2] #a[1]为[5,6,7,8],a[1][2]为7。这种方法是对元素进行递归访问。【例8】
但是递归方法比较麻烦,可以传入一个以逗号隔开的索引列表来选取单个元素。【例8】
a[0]=7 #广播的概念。不能写作"b=a[0];b=7",因为就相当于7赋值给了b。可以写“b=a[0];b[:]=7”。【例9】
a[:]=8 #a的所有元素变成8。相当于第一个轴,从头到尾。所以是所有的。
a[:1] #前一行。第一个轴从头到1(不含1),所以是前1行。返回1*4的二维数组。【15】
a[:2,1:] #“:2”表示第一个轴从头到2,为前两行。“1:”表示从第2列到最后。所以返回2*3的二维数组。【例16】
a[:,0] #取第1列。第一个轴取所有,第二个轴取0。所以为第1列。返回的是一维的数组。【例17】
a[:,:1] #取第1列。虽然与a[:,0]都是取第一列。但是结果的维度不一样。此处还是二维数组。【例17】
a[1,:2] #返回第二行的前两列。
a[:2,2] #返回第3列的前两行。
a[:2,2]=12 #对切片表达式的赋值操作也会扩散到整个选区。
#假设a=[[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]] 2*2*3的数组
a[1] #为2*3的数组。【例10】
a[1,1] #[10 11 12]。等价于a[1][1]。【例11】
a[0]=7 #广播。不能写作"b=a[0];b=7",因为就相当于7赋值给了b。可以写“b=a[0];b[:]=7”。【例12】【例13】
a[:]=8 #a的所有元素变成8。【例14】
总结:二维数组切片。当仅使用切片(冒号)时,返回的维度为2维。当切片和索引一起使用时(冒号和纯数字),返回的维度是1维。

布尔型索引:略,以后用到再说。
花式索引:略,以后用到再说。
例1:
|
a=np.arange(10)
b=a[5]
print(b) #5
c=a[5:8]
print(c) #[5,6,7]
|
例2:
|
import numpy as np
a=np.arange(10)
a[1]=5
print(a) #[0 5 2 3 4 5 6 7 8 9]
|
例3:
|
import numpy as np
a=np.arange(10)
a[5:8]=12
print(a) #[ 0 1 2 3 4 12 12 12 8 9]
|
例4:
|
import numpy as np
a=np.arange(10)
a[:]=12
print(a) #[12 12 12 12 12 12 12 12 12 12]
|
例5:
|
import numpy as np
a=np.arange(10)
print(a) #[0 1 2 3 4 5 6 7 8 9]
b=a[5:8] #[5 6 7]
print(b)
b[:]=12
print(b) #[12 12 12]
print(a) #[ 0 1 2 3 4 12 12 12 8 9]。a也跟着改变了。
|
例6:
|
import numpy as np
a=np.arange(10)
print(a)
b=a[5:8].copy() #[5,6,7]。得到的是ndarray切片的一份副本而非视图。
print(b)
b[:]=12 #[12,12,12]
print(b)
print(a) #[1,2,3,4,5,6,7,8,9]。a就不跟随b变化了。
|
例7:
|
import numpy as np
a=np.array([[1,2,3,4],
[5,6,7,8]])
b=a[1]
print(b) #[5 6 7 8]
|
例8:
|
import numpy as np
a=np.array([[1,2,3,4],
[5,6,7,8]])
b=a[1][2]
print(b) #7
c=a[1,2]
print(c) #7。这两种写法等价。
|
例9:
|
import numpy as np
a=np.array([[1,2,3,4],[5,6,7,8]])
b=a[0]
b[:]=7
print(a)
|
运行结果:
[[7 7 7 7]
[5 6 7 8]]
例10:
|
import numpy as np
a=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
b=a[1]
print(b)
|
运行结果:
[[ 7 8 9]
[10 11 12]]
例11:
|
import numpy as np
a=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
b=a[1,1]
print(b) #[10 11 12]
|
例12:
|
import numpy as np
a=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
a[0]=43
print(a)
|
运行结果:
[[[ 7 7 7]
[ 7 7 7]]
[[ 7 8 9]
[10 11 12]]]
例13:
|
import numpy as np
a=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
b=a[0]
print(b)
b[:]=7 #这个地方不能写“b=7”。这样写的话,就相当于变量b变成了7。跟数组没啥关系了。
print(a) #a如果也变化,说明不是副本。
|
运行结果:
[[1 2 3] #b
[4 5 6]]
[[[ 7 7 7] #说明不是副本。
[ 7 7 7]]
[[ 7 8 9]
[10 11 12]]]
例14:
|
import numpy as np
a=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
a[:]=8
print(a)
|
运行结果:
[[[8 8 8]
[8 8 8]]
[[8 8 8]
[8 8 8]]]
例15:
|
import numpy as np
a=np.array([[1,2,3,4],
[5,6,7,8]])
b=a[:1]
print(b)
print(b.shape)
|
运行结果:
[[1 2 3 4]] #b是一个二维数组。
(1, 4)
例16:
|
import numpy as np
a=np.array([[1,2,3,4],
[5,6,7,8]])
b=a[:2,1:]
print(b)
print(b.shape)
|
运行结果:
[[2 3 4]
[6 7 8]]
(2, 3)
例17:
|
import numpy as np
a=np.array([[1,2,3,4],
[5,6,7,8]])
print(a.shape)
b=a[:,0]
print(b)
print(b.shape)
c=a[:,:1]
print(c)
print(c.shape)
|
运行结果:
(2, 4) //a是2维的。
[1 5]
(2,) //b是一维的。
[[1]
[5]]
(2, 1) //c是2维的。
五、矩阵运算
大小相等的数组之间的任何算术运算都会将运算应用到元素级。假设以下矩阵大小相等。
1. A+B //对应元素相加。【例1】
2. A-B //对应元素相减。【例1】
3. A*B //对应元素相乘。【例1】
4. A/B //对应元素相除。【例1】
5. A%B //对应元素取余。【例1】
数组与标量的算术运算会将标量值传播到各个元素。
1. A*2 //每个元素乘以2。【例2】
2. A**0.5 //乘方。每个元素开根号。【例3】
3. 1/A //矩阵每个元素被1除。【例4】
大小相同的数组之间的比较会生成布尔值数组。
1. A>B //返回的是ndarray类型。【例5】
不同大小的数组之间的运算叫做广播(broadcasting)。附录A中单独讲。
例1:
|
import numpy as np
a=np.array([[2,4,6],[3,6,9]])
b=np.array([[1,2,3],[1,2,3]])
print(a)
print(b)
print(a+b)
print(a-b)
print(a*b)
print(a/b)
print(a%b)
|
运行结果:
[[2 4 6] #a
[3 6 9]]
[[1 2 3] #b
[1 2 3]]
[[ 3 6 9] #a+b
[ 4 8 12]]
[[1 2 3] #a-b
[2 4 6]]
[[ 2 8 18] #a*b
[ 3 12 27]]
[[2. 2. 2.] #a/b
[3. 3. 3.]]
[[0 0 0] #a%b
[0 0 0]]
例2:
|
import numpy as np
a=np.array([[1,2,3],
[2,3,4]])
b=a*2
print(b)
|
运行结果:
[[2 4 6]
[4 6 8]]
例3:
|
import numpy as np
a=np.array([[1,2,3],
[2,3,4]])
b=a**0.5
print(b)
|
运行结果:
[[1. 1.41421356 1.73205081]
[1.41421356 1.73205081 2. ]]
例4:
|
import numpy as np
a=np.array([[1,2,3],
[2,3,4]])
b=1/a
print(b)
|
运行结果:
[[1. 0.5 0.33333333]
[0.5 0.33333333 0.25 ]]
例5:
|
import numpy as np
a=np.array([[1,2,3],
[2,3,4]])
b=np.array([[0,1,2],
[3,4,5]])
c=b>a
print(c)
print(type(c))
|
运行结果:
[[False False False]
[ True True True]]
<class 'numpy.ndarray'> //C也是一个numpy数组类型。
六、线性代数
1. A.dot(B) //矩阵A乘以矩阵B。运算之后A的值并不改变。【例1】
np.dot(A,B) //另一种写法。【例1】
2. A.T //矩阵A的转置【例2】。
A.transpose()
numpy.linalg 中有一组标准的矩阵分解运算以及诸如求逆、行列式之类的东西。

例1:矩阵相乘
|
import numpy as np
A=np.array([[1,2],[3,4]])
B=np.array([[5,6],[7,8]])
C=A.dot(B) //或者C=np.dot(A,B)
print(C)
|
运行结果:
[[19 22]
[43 50]]
分析:

例2:
|
import numpy as np
A=np.array([[1,2,3],[4,5,6]])
print(A)
B=A.T //A矩阵的转置
print(B) //B为B矩阵的转置
print(A) //A矩阵没有变
|
运行结果:
[[1 2 3] //A矩阵
[4 5 6]]
[[1 4] //B矩阵
[2 5]
[3 6]]
[[1 2 3] //A矩阵没有变
[4 5 6]]
例3:
|
import numpy as np
A=np.array([[1,2,3],[4,5,6]])
B=A.transpose()
print(A)
print(B)
|
运行结果:
[[1 2 3] #A矩阵没有变
[4 5 6]]
[[1 4]
[2 5]
[3 6]]
七、通用函数
通用函数(即ufunc)是一种对ndarray的数据执行元素级运算的函数。
有的是一元函数,如:
1 np.sqrt(A) #开方。【例1】
2 np.exp(A) #各元素的指数。【例2】
另外一些接受2个数组,并返回一个结果数组,如:
1. np.maximum(A,B) #计算对应元素的最大值。【例3】
还有一些可以返回多个数组的。还有一些可以在数组原地进行操作的。以后用到再说。
下图列出了一些医院和二院ufunc。



例1:
|
import numpy as np
A=np.array([[0,1,2],
[3,4,5]])
B=np.sqrt(A)
print(B)
|
运行结果:
[[0. 1. 1.41421356]
[1.73205081 2. 2.23606798]]
例2:
|
import numpy as np
A=np.array([[0,1,2],
[3,4,5]])
B=np.exp(A)
print(B)
|
运行结果:
[[ 1. 2.71828183 7.3890561 ]
[ 20.08553692 54.59815003 148.4131591 ]]
例3:
|
import numpy as np
A=np.array([[0,1,2],
[3,4,5]])
B=np.array([[0,1,0],
[3,5,2]])
C=np.maximum(A,B)
print(C)
|
运行结果:
[[0 1 2]
[3 5 5]]
八、数组统计方法
1. mean(A) #全部元素的均值。【例1】
2. max(A) #全部元素的最大值。【例1】
3. min(A) #全部元素的最小值。【例1】
4. sum(A) #全部元素的和。【例1】
5. cumsum(A) #累加。还是得到一个数组。【例2】
例1:
|
import numpy as np
A=np.array([[0,1,2],
[3,4,5]])
b=np.mean(A)
print(b) #2.5
c=np.max(A)
print(c) #5
d=np.sum(A)
print(d) #15
e=np.min(A)
print(e) #0
|
例2:
|
import numpy as np
A=np.arange(5)
B=np.cumsum(A)
print(B) #[ 0 1 3 6 10]
|
九、排序
1 np.sort(A) //A的值没有改变。返回的是数组的已排序副本。【例1】
2 A.sort() //A的值改变了。就地排序。【例2】
例1:
|
import numpy as np
A=np.array([0,2,1,3,5,4,2])
np.sort(A)
print(A) #[0 2 1 3 5 4 2]。A的值本身没有变化。
B=np.sort(A)
print(B) #[0 1 2 2 3 4 5]。
|
例2:
|
import numpy as np
A=np.array([0,2,1,3,5,4,2])
A.sort()
print(A) #[0 1 2 2 3 4 5]。A的值改变了。
|
十、伪随机数生成
np.random.random((5,6)) #生成5*6矩阵,元素为[0,1)范围的随机数。【例1】
np.random.randn(5,4) #生成5*4矩阵,生成的服从均值为0,方差为1的正态分布的数据。【例2】
np.random.normal(10,2,size=20) #生成服从均值为10,标准差为2的20个数。【例3】
np.random.rand(5) #产生均匀分布的样本值。范围[0,1)。
随机数种子:
np.random.seed(123) #我们说这些都是伪随机数,是因为它们都是通过算法基于随机数生成器种子,在确定性的
条件下生成的。可以设置种子,使得产生相同的随机数。【例4】
rng=numpy.random.RandomState(123) #numpy.random的数据生成函数使用了全局的随机种子。要避免全局状态,你可以
使用numpy.random.RandomState,创建一个与其它隔离的随机数生成器。【例5】
#要使用rng变量生成随机数。
例1:
|
import numpy as np
A=np.random.random((5,6))
print(A)
|
运行结果:
[[0.45725536 0.51749584 0.37011497 0.31930555 0.36831096 0.2982471 ]
[0.45022233 0.84690051 0.5126663 0.07385434 0.38853684 0.30396522]
[0.4699983 0.2917169 0.04820421 0.95568688 0.07040655 0.12968868]
[0.480243 0.24259097 0.63156488 0.65321587 0.13144595 0.32945552]
[0.81848384 0.36788052 0.83688598 0.44025479 0.87562299 0.58541739]]
例2:
|
import numpy as np
A=np.random.randn(5,4)
print(A)
|
运行结果:
[[ 1.2068138 -0.38949578 -0.33382822 1.86522222]
[ 0.15415726 0.30539664 -0.40072915 0.2337047 ]
[ 0.19410037 0.0065038 -0.12551592 0.71778806]
[-1.0274531 -0.36558762 -0.42966111 0.74373768]
[ 1.0213819 1.2060192 0.84799635 2.11356245]]
例3:
|
import numpy as np;
x=np.random.normal(10,2,5)
print(x)
x=np.random.normal(10,2,5) #可以看到两次生成的随机数不同。
print(x)
|
运行结果:
[ 9.84885657 12.26325877 13.03963363 14.37115081 7.20700733]
[ 7.11177239 8.99106827 10.32007414 11.75233784 10.63126989]
例4:
|
import numpy as np
np.random.seed(1)
x=np.random.randn(5)
print(x)
y=np.random.randn(5)
print(y) #y与x不相等了。说明随机数种子管一次用。
np.random.seed(1)
z=np.random.randn(5)
print(z) #z与x一样。因为都是基于同一个种子。
|
运行结果:
[ 1.62434536 -0.61175641 -0.52817175 -1.07296862 0.86540763]
[-2.3015387 1.74481176 -0.7612069 0.3190391 -0.24937038]
[ 1.62434536 -0.61175641 -0.52817175 -1.07296862 0.86540763] #z与x一样。
例5:
|
import numpy as np
np.random.seed(123) #全局的随机数种子。
x=np.random.rand(5) #生成了一个均匀分布的5个数。
y=np.random.rand(5) #又生成了一个均匀分布的5个数。y与x不一样。
print(x)
print(y)
rng=np.random.RandomState(123) #设置了局部的随机数种子。
z=rng.rand(5) #z也是用的123种子,所以z的值跟x的值完全一样。
p=rng.rand(5) #p是局部种子生成的第二个数,跟全局种子生成的第二个数y一样。
t=rng.rand(5) #t是局部种子生成的第三个数。
print(z)
print(p)
print(t)
q=np.random.rand(5) #q是全局种子生成的第三个随机数。跟局部种子生成的第三个数t一样
print(q)
|
运行结果:
[0.69646919 0.28613933 0.22685145 0.55131477 0.71946897] //全局种子第一个数
[0.42310646 0.9807642 0.68482974 0.4809319 0.39211752] //全局种子第二个数
[0.69646919 0.28613933 0.22685145 0.55131477 0.71946897] //局部种子第一个数
[0.42310646 0.9807642 0.68482974 0.4809319 0.39211752] //局部种子第二个数
[0.34317802 0.72904971 0.43857224 0.0596779 0.39804426] //局部种子第三个数
[0.34317802 0.72904971 0.43857224 0.0596779 0.39804426] //全局种子第三个数
十一、数组重塑
1. a.reshape(3,2) //变换形状。得到的是A的改变形状的视图。【例1】【例2】【例3】
//多维数组也可以重塑。【例4】
2. a.resize(3,2) //改变a的形状。【例7】
3. a.flatten() //摊平。返回a的副本,不是视图。深拷贝。【例5】
4. a.ravel() //摊平。返回的结果是a的视图。浅拷贝。【例6】
例1:
|
import numpy as np
a=np.arange(10)
print(a) #[0 1 2 3 4 5 6 7 8 9]
b=a.reshape(2,5);
print(a) #[0 1 2 3 4 5 6 7 8 9]。说明a不改变。
print(b) #2行5列
|
运行结果:
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4]
[5 6 7 8 9]]
例2:
|
import numpy as np
A=np.arange(10) #[0 1 2 3 4 5 6 7 8 9]
print(A)
A.reshape(2,5)
print(A) #[0 1 2 3 4 5 6 7 8 9]。说明A并没有改变。
|
例3:
|
import numpy as np
A=np.arange(10)
print(A) #[0 1 2 3 4 5 6 7 8 9]
B=A.reshape(2,5)
print(B) #2*5的矩阵
B[0,0]=12
print(B) #B的值改变了。
print(A) #A的值也改变了。说明B是A的视图。
|
运行结果:
[0 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4]
[5 6 7 8 9]]
[[12 1 2 3 4]
[ 5 6 7 8 9]]
[12 1 2 3 4 5 6 7 8 9]
例4:
|
import numpy as np
A=np.arange(10).reshape(2,5)
B=A.reshape(5,2)
print(A)
print(B)
|
运行结果:
[[0 1 2 3 4]
[5 6 7 8 9]]
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
例5:
|
import numpy as np
A=np.arange(10).reshape(2,5)
print(A)
A.flatten() #执行这一句之后,A并不改变。还是2*5。
print(A)
B=A.flatten() #B为一行。
print(B)
B[0]=12 #执行这一句之后,B的值变了。但是A的值没有改变。说明B是A的副本。B和A不是同一个地址。
print(B)
print(A)
|
运行结果:
[[0 1 2 3 4]
[5 6 7 8 9]]
[[0 1 2 3 4]
[5 6 7 8 9]]
[0 1 2 3 4 5 6 7 8 9]
[12 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4]
[5 6 7 8 9]]
例6:
|
import numpy as np
A=np.arange(10).reshape(2,5)
print(A)
A.ravel() #执行这一句之后,A并不改变。还是2*5。
print(A)
B=A.ravel() #B为一行。
print(B)
B[0]=12 #执行这一句之后,B的值变了。A的值也变了。说明B是A的视图。B和A是同一个地址。
print(B)
print(A)
|
运行结果:
[[0 1 2 3 4]
[5 6 7 8 9]]
[[0 1 2 3 4]
[5 6 7 8 9]]
[0 1 2 3 4 5 6 7 8 9]
[12 1 2 3 4 5 6 7 8 9]
[[12 1 2 3 4]
[ 5 6 7 8 9]]
例7:
|
import numpy as np
A=np.arange(10).reshape(2,5)
A.resize(5,2)
print(A)
|
运行结果:
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
十二、数组的合并和拆分
1 vstack((A,B)) //以面向行的方式对数组进行堆叠(沿轴0)。【例1】
2 hstack((A,B)) //以面向列的方式对数组进行堆叠(沿轴1)。【例2】
3 np.c_[A,B] //NumPy命名空间中有两个特殊的对象——r_和c_,它们可以使数组的堆叠操作更为简洁。
4 np.r_[A,B] np.c_是按行连接两个矩阵,就是把两矩阵左右相加,要求行数相等。【例3】【例5】
np.r_是按列连接两个矩阵,就是把两矩阵上下相加,要求列数相等。【例4】【例5】

例1:
|
import numpy as np
A=np.array([[1,2],
[3,4]])
B=np.eye(2)
C=np.vstack((A,B))
print(C)
A[1]=6
print(A)
print(C) #A改变之后C不改变。说明是深拷贝。
|
运行结果:
[[1. 2.]
[3. 4.]
[1. 0.]
[0. 1.]]
[[1 2]
[6 6]]
[[1. 2.]
[3. 4.]
[1. 0.]
[0. 1.]]
例2:
|
import numpy as np
A=np.array([[1,2],
[3,4]])
B=np.eye(2)
C=np.hstack((A,B))
print(C)
A[1]=6
print(A)
print(C) #A改变之后C不改变。说明是深拷贝。
|
运行结果:
[[1. 2. 1. 0.]
[3. 4. 0. 1.]]
[[1 2]
[6 6]]
[[1. 2. 1. 0.]
[3. 4. 0. 1.]]
例3:
|
import numpy as np
x=np.array([[1,2,3],[4,5,6]])
y=np.array([[7,8],[9,10]])
z=np.c_[x,y]
print(x)
print(y)
print(z)
|
运行结果:

例4:
|
import numpy as np
x=np.array([[1,2],[3,4]])
y=np.array([[5,6],[7,8],[9,10]])
z=np.r_[x,y]
print(x)
print(y)
print(z)
|
运行结果:

例5:
|
import numpy as np
x=np.array([1,2,3,4])
y=np.array([5,6,7,8])
z=np.r_[x,y]
t=np.c_[x,y]
print(x)
print(y)
print(z)
print(t)
|
运行结果:

这个地方很奇怪,按照正常理解,x=[1,2,3,4] ,y=[5,6,7,8],np_c[x,y]得到的应该是[1,2,3,4,5,6,7,8]。但是这个输出结果,跟想象的刚好反了。可以这样想:x=np.array([1,2,3,4])生成的是列向量。这样想的话,就对了。
|