Numpy
- 初识
- ①what + ②how + ③why
①
Numpy——Numerical Python (地基型)
是一个 开源的 Python 科学计算库
②
主要的功能之一用来操作数组和矩阵
是科学计算、深度学习等高端领域的必备工具
使用TensorFlow、Caffe框架训练神经网络模型时,需要进行大量复杂的运算,可以直接调用Numpy里面的API
NumPy还包含了很多使用的数学函数,覆盖了很多的数学领域,比如线性代数、傅里叶变换、随机数生成
③
核心算法由C语言编写,执行效率高
扩展性非常好,容易集成到其他语言中
- ndarray(N-dimensional array ?
在numpy里,ndarray是整个numpy的基础,ndarray是N-dimensional array的缩写。它是一种由同质元素组成的多维数组。
元素数量是事先准备好的,同质指的是所有的元素类型一致。
ndarray数据类型由一个叫dtype的numpy对象指定,每个ndarray只有一种dtype类型。
数组的维数和元素数量由数组的型(shape)来确定。shape由n个正整数组成的元组来指定,元组的每个元素对应每一维的大小,数组的维统称为轴(axis),轴的数量叫做秩(rank).
ndarray还有一个特点就是大小固定,创建ndarray一旦指定了大小,其大小就不会再发生改变,而python列表是可以改变的。
使用array()函数定义,以python列表作为参数,创建之后列表的元素就是ndarray的元素。
查看ndarray类型中一些基本属性
属性 | 描述 |
---|---|
ndarray.ndim | 数组轴的个数,也被称作秩 |
ndarray.shape | 数组在每个维度上大小的整数元组 |
ndarray.size | 数组元素的总个数 |
ndarray.dtype | 数组元素的数据类型,dtype 类型可以用于创建数组中 |
ndarray.itemsize | 数组中每个元素的字节大小 |
ndarray.data | 包含实际数组元素的缓冲区地址 |
ndarray.flat | 数组元素的迭代器 |
list ? ndarray
>>>#导入numpy
>>>import numpy as np
>>>a = [1,2,3,4,5,6,7,8,9]
>>>print(a)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>a * 2 #表示复制 非做数乘运算
[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>print(type(a))
<class 'list'>
>>>#把普通python中的list转换成ndarray
>>>A = np.array(a)
>>>print(A)
>>>A
[1 2 3 4 5 6 7 8 9]
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>>print(type(A))
<class 'numpy.ndarray'>
>>>A * 2 #轻松完成数乘运算
array([ 2, 4, 6, 8, 10, 12, 14, 16, 18])
创建数组
>>>#直接创建一维数组
>>>b = np.array([1,2,3,4,5])
>>>print(b)
>>>print(type(b))
[1 2 3 4 5]
<class 'numpy.ndarray'>
>>>b * 6
array([ 6, 12, 18, 24, 30])
>>>#创建多维数组
>>>c = np.array([[1,2,3],[4,5,6]])
>>>print(c)
>>>print(type(c))
[[1 2 3]
[4 5 6]]
<class 'numpy.ndarray'>
>>>c * 2
array([[ 2, 4, 6],
[ 8, 10, 12]])
>>>cc = [[1,2,3],[4,5,6]]
>>>cc * 2
[[1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6]]
>>>print(c.ndim) #数组的维度 → 看 中括号 的个数
>>>print(c.shape)#返回元组 → 二维数组(行,列)
>>>print(c.size) #包含元素个数
2
(2, 3)
6
.dtype 查看ndarray的数据类型
>>>#指定维度来创建多维数组(懒得打中括号时)
>>>n = np.array([[[1,2,3,4,5,6]]]) #对比
>>>e = np.array([1,2,3,4,5,6], ndmin=3)
>>>print(n)
>>>print(e)
[[[1 2 3 4 5 6]]]
[[[1 2 3 4 5 6]]]
>>>#指定维度和数值来创建多维数组
>>>f = np.array([1,2,3,4,5,6], ndmin=3, dtype=np.complex)
>>>print(f)
[[[1.+0.j 2.+0.j 3.+0.j 4.+0.j 5.+0.j 6.+0.j]]]
>>>e.dtype
dtype('int32')
>>>type(e) #仅知是numpy里的数组,但不知数组内部元素的类型
numpy.ndarray
属性.ndim .shape .size
>>>d = np.array([[[1,2,3],[4,5,6],[7,8,9]]])
>>>print(d)
>>>print(d.ndim) #数组的维度 → 看 中括号 的个数
>>>print(d.shape) #返回元组 → 三维数组(最外层中括号内仅包裹一个元素,行,列)
>>>print(d.size) #包含元素个数
[[[1 2 3]
[4 5 6]
[7 8 9]]]
3
(1, 3, 3)
9
>>>dd = np.array([[[1,2,3],[4,5,6],[7,8,9]],[[1,2,3],[4,5,6],[7,8,9]]])
>>>print(dd)
>>>print(dd.ndim)
>>>print(dd.shape)
>>>print(dd.size)
[[[1 2 3]
[4 5 6]
[7 8 9]]
[[1 2 3]
[4 5 6]
[7 8 9]]]
3
(2, 3, 3)
18
>>>#可以通过修改数组的shape属性,在保持数组元素个数不变的情况下,改变数组每个轴的长度。
>>>g = np.array([[1,2,3,4],[4,5,6,7],[7,8,9,10]])
>>>print(g)
[[ 1 2 3 4]
[ 4 5 6 7]
[ 7 8 9 10]]
从(3,4)改为(4,3)并不是对数组进行转制,而只是改变每个轴的大小,数组元素在内存中的位置并没有改变。
>>>g.shape = 4,3
>>>print(g)
[[ 1 2 3]
[ 4 4 5]
[ 6 7 7]
[ 8 9 10]]
当某个轴的元素为-1时,将根据数组元素的个数自动计算此轴的长度。
>>>g.shape = 2,-1
>>>print(g) #保证能被2整除
[[ 1 2 3 4 4 5]
[ 6 7 7 8 9 10]]
reshape
使用数组reshape方法,可以创建一个改变了尺寸的新数组,原数组的shape保持不变。
>>>h = g.reshape(6,2)
>>>print(h)
[[ 1 2]
[ 3 4]
[ 4 5]
[ 6 7]
[ 7 8]
[ 9 10]]
- Numpy基础之数组创建 ?
上面的例子都是先创建一个Python序列,然后通过array函数将其转换为数组,这样做显然效率不高。
因此NumPy提供了很多专门用来快速高效创建数组的函数
系列函数用法汇总博客?
函数 | 功能 |
---|---|
numpy.empty() | 初始化一个矩阵为指定尺寸的矩阵 |
numpy.zeros() | 创建以 0 为元素的矩阵 |
numpy.zeros_like() | 生成一个与已有矩阵具有相同尺寸的零矩阵 |
numpy.ones() | 生成元素全为 1 的矩阵 |
numpy.ones_like() | 生成与输入矩阵具有相同形状的元素为 1 的矩阵 |
numpy.eye() | 创建对角矩阵是对角线上元素为 1,其他位置元素为 0 的矩阵 |
numpy.empty()以随机的方式来创建数组
>>>a = np.empty([3,2], dtype=np.int32)
>>>print(a)
[[0 0]
[0 0]
[0 0]]
numpy.zeros返回返回指定大小的数组,并以0作为填充
>>>b = np.zeros([5,6], dtype=np.float32)
>>>print(a)
[[0 0]
[0 0]
[0 0]]
numpy.zeros_like()
>>>c = np.array([[1,2,3],[4,5,6]], dtype=np.float32)
>>>print(c)
[[1. 2. 3.]
[4. 5. 6.]]
>>>d = np.zeros_like(c)
>>>print(d)
[[0. 0. 0.]
[0. 0. 0.]]
numpy.ones()、numpy.ones_like()
>>>e = np.ones_like(c)
>>>print(e)
[[1. 1. 1.]
[1. 1. 1.]]
numpy.eye函数返回对角线为1,其余为零的数组
>>>d = np.eye(5)
>>>print(d)
[[1. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 0. 1.]]
>>>d = np.eye(5,dtype=np.int32)
>>>print(d)
[[1 0 0 0 0]
[0 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 0]
[0 0 0 0 1]]
函数 | 功能 |
---|---|
numpy.asarray() | 将list和元组转换成ndarray |
numpy.arange() | 通过指定开始值、终值和步长来创建一维数组 |
numpy.linspace() | 通过指定开始值、终值和元素个数来创建一维数组 |
numpy.logspace() | 创建等比数列 |
arange函数类似于python的range函数,通过指定开始值、终值和步长来创建一维数组,注意数组不包括终值。
>>>x = np.arange(10)
>>>print(type(x))
>>>print(x)
<class 'numpy.ndarray'>
[0 1 2 3 4 5 6 7 8 9]
>>>x = np.arange(10, dtype=np.float32)
>>>print(x)
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
>>>x = np.arange(10,20,2, dtype=np.int32)
>>>print(x)
[10 12 14 16 18]
linspace函数通过指定开始值、终值和元素个数来创建一维数组,可以通过endpoint关键字指定是否包括终值。
>>>x = np.linspace(10,20,5)
>>>print(x) #害,植树问题,首尾都种
[10. 12.5 15. 17.5 20. ]
>>>x = np.linspace(0,1,10)
>>>print(x)
[0. 0.11111111 0.22222222 0.33333333 0.44444444 0.55555556
0.66666667 0.77777778 0.88888889 1. ]
>>>x = np.linspace(0,1,10, endpoint=False)
>>>print(x)
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
>>>x = np.linspace(0.1,1.1,10, endpoint=False)
>>>print(x)
[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]
logspace函数与linspace类似,不过它创建等比数列,下面的例子产生1-100,有20个元素的等比数列。
>>>np.logspace(0,2,20)
array([ 1. , 1.27427499, 1.62377674, 2.06913808,
2.6366509 , 3.35981829, 4.2813324 , 5.45559478,
6.95192796, 8.8586679 , 11.28837892, 14.38449888,
18.32980711, 23.35721469, 29.76351442, 37.92690191,
48.32930239, 61.58482111, 78.47599704, 100. ])
numpy.asarray()主要时把python中的list和元组转换成numpy中的ndarray。
>>>x = [1,2,3,4,5,6]
>>>a = np.asarray(x)
>>>print(type(x))
>>>print(type(a))
>>>print(x)
>>>print(a)
<class 'list'>
<class 'numpy.ndarray'>
[1, 2, 3, 4, 5, 6]
[1 2 3 4 5 6]
- 存取元素
数组元素的存取方法和python的标准方法相同
>>>a = np.arange(10)
>>>a[5] #用整数作为下标可以获得数组中的某个元素
5
>>>a[3:5] #用范围作为下标获取数组的一个切片,包括a[3]不包括a[5]
array([3, 4])
>>>a[:5]
array([0, 1, 2, 3, 4])
>>>a[:-1]
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
下标还可以用来修改元素的值
>>>a[2:4] = 100,101
>>>a
array([ 0, 1, 100, 101, 4, 5, 6, 7, 8, 9])
>>>print(a[1:-1:2])
[ 1 101 5 7]
和Python的列表序列不同,通过下标范围获取的新的数组时原始数组的一个视图,
它与原始数组共享同一块数据空间。
>>>a
array([ 0, 1, 100, 101, 4, 5, 6, 7, 8, 9])
>>>b = a[3:7]
>>>b
array([101, 4, 5, 6])
>>>b[2] = -10
>>>b
array([101, 4, -10, 6])
>>>b
>array([101, 4, -10, 6])
In [61]:
>>>a #由b改变a也变了
array([ 0, 1, 100, 101, 4, -10, 6, 7, 8, 9])
使用整数序列
当使用整数序列对数组元素进行存取时,将使用整数序列中的每个元素作为下标,整数序列可以是列表或数组。
使用整数序列作为下标获得的数组不和原始数组共享数据空间。
>>>x = np.arange(10,1,-1)
>>>x
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>>x[[3,3,1,8]] #获取x中的下标为3,3,1,8的4个元素,组成一个新的数组
array([7, 7, 9, 2])
>>>b = x[np.array([3,3,-3,8])]
>>>b
array([7, 7, 4, 2])
>>>b[2] = 100
>>>b
>array([ 7, 7, 100, 2])
>>>x #由于b和x不共享数据空间,因此b改变不影响x的值
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
#整数序列下标也可以用来修改元素的值
>>>x[[3,5,1]] = -1, -2, -3
>>>x
array([10, -3, 8, -1, 6, -2, 4, 3, 2])
当使用布尔数组b作为下标存取数组x中的元素时,将收集数组x中所有再数组b中对应下标为True的元素。
使用布尔数组作为下标获得的数组不和原始数组共享数据空间,
注意这种方式只对应于布尔数组,不能使用布尔列表。
>>>x = np.arange(5,0,-1)
>>>x
array([5, 4, 3, 2, 1])
>>>x[np.array([True, False,True, False, False])]
array([5, 3])
>>>x[np.array([True, False,True, True, False])] = -1, -2 ,-3
>>>x
array([-1, 4, -2, -3, 1])
>>>x = np.random.rand(10)
>>>x
array([0.48288798, 0.80541831, 0.39553682, 0.05104537, 0.38070458,
0.09673533, 0.51242822, 0.69705971, 0.95072 , 0.16686176])
>>>x[x > 0.5]
array([0.80541831, 0.51242822, 0.69705971, 0.95072 ])
- NumPy之广播
广播是指NumPy在算术运算期间处理不同形状的数组的能力。对数组的算术运算通常在相应的元素上进行。如果两个阵列具有完全相同的形状,则这些操作被无缝执行。
如果两个数组的维数不相同,则元素到元素的操作时不可能的。然而,在NumPy中仍然可以对形状不相似的数组进行操作,因为它拥有广播功能。较小的数组会广播到较大的数组的大小,从而使它们的形状可以兼容。
同维矩阵操作
>>>a = np.array([1,2,3,4,5])
>>>b = np.array([10,20,30,40,50])
>>>#相加
>>>print(a+b)
[11 22 33 44 55]
>>>#相乘
>>>print(a*b)
[ 10 40 90 160 250]
>>>#相减
>>>print(a-b)
[ -9 -18 -27 -36 -45]
不同维度矩阵操作,就需要使用广播
>>>a = np.array([[1,1,1],[10,10,10],[20,20,20]])
>>>b = np.array([1,2,3])
>>>print("矩阵a")
>>>print(a)
>>>print("矩阵b")
>>>print(b)
矩阵a
[[ 1 1 1]
[10 10 10]
[20 20 20]]
矩阵b
[1 2 3]
>>>#a+b
>>>print(a+b)
[[ 2 3 4]
[11 12 13]
[21 22 23]]
>>>#a*b
>>>print(a*b)
[[ 1 2 3]
[10 20 30]
[20 40 60]]
>>>#a-b
>>>print(a-b)
[[ 0 -1 -2]
[ 9 8 7]
[19 18 17]]
? END