Python学习记录8——Numpy模块的深入了解学习(记录API)
Posted 康娜喵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习记录8——Numpy模块的深入了解学习(记录API)相关的知识,希望对你有一定的参考价值。
零之前言
因为后面机器学习需要使用到np,所以需要更高要求的了解Numpy这个包,我就根据菜鸟论坛上面的Numpy教程来学习并记录了。
参考:菜鸟教程-NumPy Ndarray 对象
一.创建Ndarray对象
1.概念
先看看创建ndaary对象的参数
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
名称 | 描述 |
---|---|
object | 传入数组 |
dtype | 数据类型,可选 |
copy | 对象是否需要复制,可选 |
order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指定生成数组的最小维度 |
然后我们运行来看看效果
import numpy as np
2.返回类型
type(np.array([1,2,3]))
numpy.ndarray
3.传入数组
np.array([1,2,3])
array([1, 2, 3])
np.array([[1,2,3],[3,4,5]])
array([[1, 2, 3],
[3, 4, 5]])
4.最小维度
np.array([[1,2],[3,4]], ndmin = 3)
array([[[1, 2],
[3, 4]]])
5.类型
np.array([1,2],dtype=np.complex)
array([1.+0.j, 2.+0.j])
二.数据类型
数据类型 | 范围与说明 |
---|---|
bool_ | 布尔型数据类型(True 或者 False) |
int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) |
intc | 与 C 的 int 类型一样,一般是 int32 或 int 64 |
intp | 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64) |
int8 | 字节(-128 to 127) |
int16 | 整数(-32768 to 32767) |
int32 | 整数(-2147483648 to 2147483647) |
int64 | 整数(-9223372036854775808 to 9223372036854775807) |
uint8 | 无符号整数(0 to 255) |
uint16 | 无符号整数(0 to 65535) |
uint32 | 无符号整数(0 to 4294967295) |
uint64 | 无符号整数(0 to 18446744073709551615) |
float_ | float64 类型的简写 |
float16 | 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位 |
float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位 |
float64 | 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位 |
complex_ | complex128 类型的简写,即 128 位复数 |
complex64 | 复数,表示双 32 位浮点数(实数部分和虚数部分) |
complex128 | 复数,表示双 64 位浮点数(实数部分和虚数部分) |
当然,也可以自定义数据类型,详细请看:NumPy 数据类型
三.数组属性(ndaary的属性)
参数 | 说明 |
---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n * m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
ndarray.flags | ndarray 对象的内存信息 |
ndarray.real | ndarray元素的实部 |
ndarray.imag | ndarray 元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
1.秩ndim
a = np.arange(24)
b = a.reshape(2,4,3)
print(a,a.ndim)
print(b,b.ndim)
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] 1
[[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
[[12 13 14]
[15 16 17]
[18 19 20]
[21 22 23]]] 3
2.维度shape
调用shape是这个数组的维度,而维度的长度和位秩,继续使用上面的a,b两个例子
print(a.shape)
print(b.shape)
(24,)
(2, 4, 3)
a.shape = (4,3,2)
print(a, a.ndim)
[[[ 0 1]
[ 2 3]
[ 4 5]]
[[ 6 7]
[ 8 9]
[10 11]]
[[12 13]
[14 15]
[16 17]]
[[18 19]
[20 21]
[22 23]]] 3
其他的属性,并没有什么好说的了。
四.创建数组
1.empty
创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组:
numpy.empty(shape, dtype = float, order = 'C')
参数 | 描述 |
---|---|
shape | 数组形状 |
dtype | 数据类型,可选 |
order | 有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。 |
np.empty([3,2], dtype = int,order = "C")
array([[7022643874161258350, 6715465368541538412],
[3683993085686784044, 6716028318494960733],
[8746397786910107997, 7310305785200466728]])
2.zeros
创建指定大小的数组,数组元素以 0 来填充:
np.zeros([3,2], dtype = int, order = 'F')
array([[0, 0],
[0, 0],
[0, 0]])
3.ones
创建指定大小的数组,数组元素以 1 来填充:
np.ones([3,2], dtype = np.int8, order = 'C')
array([[1, 1],
[1, 1],
[1, 1]], dtype=int8)
4.asarray
numpy.asarray 类似 numpy.array,但 numpy.asarray 参数只有三个,比 numpy.array 少两个
numpy.asarray(a, dtype = None, order = None)
参数 | 描述 |
---|---|
a | 任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组 |
dtype | 数据类型,可选 |
order | 可选,有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。 |
np.asarray([(1,2,3),(4,5)])
array([(1, 2, 3), (4, 5)], dtype=object)
但是这样就会报错,因为我们是列表里镶嵌元组,所以与int8类型是不匹配的
np.asarray([(1,2,3),(4,5)],dtype=np.int8)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-42-f73712c57ed0> in <module>()
----> 1 np.asarray([(1,2,3),(4,5)],dtype=np.int8)
~/anaconda3/lib/python3.7/site-packages/numpy/core/numeric.py in asarray(a, dtype, order)
499
500 """
--> 501 return array(a, dtype, copy=False, order=order)
502
503
ValueError: setting an array element with a sequence.
5.arange
numpy.arange(start, stop, step, dtype)
通过等差数列创建对象
参数 | 描述 |
---|---|
start | 起始值,默认为0 |
stop | 终止值(不包含) |
step | 步长,默认为1 |
dtype | 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。 |
print(np.arange(5))
print(np.arange(0,12,2,dtype=np.complex))
[0 1 2 3 4]
[ 0.+0.j 2.+0.j 4.+0.j 6.+0.j 8.+0.j 10.+0.j]
6.linspace
类似于上面的, 函数用于创建一个一维数组,数组是一个等差数列构成的,格式如下:
参数 | 描述 |
---|---|
start | 序列的起始值 |
stop | 序列的终止值,如果endpoint为true,该值包含于数列中 |
num | 要生成的等步长的样本数量,默认为50 |
endpoint | 该值为 true 时,数列中中包含stop值,反之不包含,默认是True。 |
retstep | 如果为 True 时,生成的数组中会显示间距,反之不显示。 |
dtype | ndarray 的数据类型 |
print(np.linspace(1,10,10,dtype=np.int8))
[ 1 2 3 4 5 6 7 8 9 10]
7.其他
还有很多函数没记录,有些是在后面,和线性代数相关的,有些是感觉用处不多的,如frombuffer
fromiter
五.数据切片和索引
暂且可理解为提取有用数据。
例:
a = np.arange(10)
a[2:7:2]
array([2, 4])
其中,[2:7:2] 可以解释为从索引 2 开始到索引 7 停止,间隔为 2,而对于该冒号可以解释为成
如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。如果为 [2:],表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项。
那么,就可以理解为[2:5:1]=[x|2<=x<5 ∩ x=N[=[[2,3,4]],对,一个或一组冒号会多增加一个[]
多维数组也支持这种理解:
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
print('从数组索引 a[1:] 处开始切割')
print(a[1:])
[[1 2 3]
[3 4 5]
[4 5 6]]
从数组索引 a[1:] 处开始切割
[[3 4 5]
[4 5 6]]
切片还可以包括省略号 …,来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的 ndarray
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[...,1])
print(a[...,1:2])
print(a[...,2:3])
print(a[...,1:])
[2 5 8]
[[2]
[5]
[8]]
[[3]
[6]
[9]]
[[2 3]
[5 6]
[8 9]]
六.高级索引
1.整数数组索引
比如下图所示的就是取(0,0)(1,1)(2,0)
x = np.array([[1, 2], [3, 4], [5, 6]])
print(x[[0,1,2], [0,1,0]])
print(x[[0], [0,1,0]])
[1 4 5]
[1 2 1]
当我们知道以上这种方法后,我们可以还原: …表达式来看
这个是二维数组的切片方法:
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[1:2,0:1])
print("-----------")
print(a[1:2,[0,1]])
print("-----------")
print(a[:2,1:])
print("-----------")
[[4]]
-----------
[[4 5]]
-----------
[[2 3]
[5 6]]
-----------
1:2 = [1]; 0:1 = [0]; a[1:2,0:1] = a[[1],[0]] = [[4]]
1:2 = [1]; a[1:2,[0,1]] = a[[1],[0,1]] = [[4 5]]
:2 = [0,1]; 1: = [1,2] = a[[0,1],[1,2]]
通过还原表达式,就可以具体知道其意思
2.布尔索引
简单明了
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
a[a > 2]
array([3, 4, 5, 6, 7, 8, 9])
3.花式索引
花式索引指的是利用整数数组进行索引。
花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行。
花式索引跟切片不一样,它总是将数据复制到新数组中。
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[[0,2]])
print("---")
print(a[[2,1,0]])
[[1 2 3]
[7 8 9]]
---
[[7 8 9]
[4 5 6]
[1 2 3]]
七.广播
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。其方式大概像这样:
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([1,2,3])
print(a + b)
[[ 1 2 3]
[11 12 13]
[21 22 23]
[31 32 33]]
广播的规则:
- 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
- 输出数组的形状是输入数组形状的各个维度上的最大值。
- 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
- 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
- 数组拥有相同形状。
- 当前维度的值相等。
- 当前维度的值有一个是 1。
若条件不满足,抛出 “ValueError: frames are not aligned” 异常。
八.迭代(遍历)
1.控制方向
for x in np.nditer(a, order='F')
:Fortran order,即是列序优先;
for x in np.nditer(a.T, order='C')
:C order,即是行序优先;
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
print ('\\n')
print ('原始数组的转置是:')
b = a.T
print (b)
print ('\\n')
print ('以 C 风格顺序排序:')
c = b.copy(order='C')
print (c)
for x in np.nditer(c):
print (x, end=", " )
print ('\\n')
print ('以 F 风格顺序排序:')
c = b.copy(order='F')
print (c)
for x in np.nditer(c):
print (x, end=", " )
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
原始数组的转置是:
[[ 0 20 40]
[ 5 25 45]
[10 30 50]
[15 35 55]]
以 C 风格顺序排序:
[[ 0 20 40]
[ 5 25 45]
[10 30 50]
[15 35 55]]
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,
以 F 风格顺序排序:
[[ 0 20 40]
[ 5 25 45]
[10 30 50]
[15 35 55]]
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,
2.修改元素的值
nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定 read-write
或者 write-only
的模式。
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
print ('\\n')
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print ('修改后的数组是:')
print (a)
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
修改后的数组是:
[[ 0 10 20 30]
[ 40 50 60 70]
[ 80 90 100 110]]
3.其他
外部循环与广播循环看起来不常用,就不记了。
九.数组操作
1.修改数组形状
①reshape
numpy.reshape 函数可以在不改变数据的条件下修改形状,格式如下: numpy.reshape(arr, newshape, order=‘C’)
- arr:要修改形状的数组
- newshape:整数或者整数数组,新的形状应当兼容原有形状
- order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。
a = np.arange(8)
a.reshape(4,2)
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
②ndarray.flat
numpy.ndarray.flat 是一个数组元素迭代器,实例如下:
a = np.arange(9).reshape(3,3)
for element in a.flat:
print (element)
0
1
2
3
4
5
6
7
8
③ndarray.flatten
umpy.ndarray.flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组,格式如下:
ndarray.flatten(order='C')
- order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘K’ – 元素在内存中的出现顺序。
a = np.arange(8).reshape(2,4)
print (a.flatten(order = 'A'))
print ('\\n')
print (a.flatten(order = 'C'))
print ('\\n')
print (a.flatten(order = 'F'))
[0 1 2 3 4 5 6 7]
[0 1 2 3 4 5 6 7]
[0 4 1 5 2 6 3 7]
④ravel
numpy.ravel() 展平的数组元素,顺序通常是"C风格",返回的是数组视图(view,有点类似 C/C++引用reference的意味),修改会影响原始数组。
numpy.ravel(a, order='C')
- order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘K’ – 元素在内存中的出现顺序。
效果差不多同上,就不赘述
2.翻转数组
①transpose
`numpy.transpose(arr, axes)`
-
arr:要操作的数组
-
axes:整数列表,对应维度,通常所有维度都会对换。
a = np.arange(9).reshape(3,3)
print (np.transpose(a))
[[0 3 6]
[1 4 7]
[2 5 8]]
②.ndarray.T
numpy.ndarray.T 类似 numpy.transpose:
a = np.arange(9).reshape(3,3)
print (a.T)
[[0 3 6]
[1 4 7]
[2 5 8]]
③.rollaxis
numpy.rollaxis 函数向后滚动特定的轴到一个特定位置,格式如下:
numpy.rollaxis(arr, axis, start)
- arr:数组
- axis:要向后滚动的轴,其它轴的相对位置不会改变
- start:默认为零,表示完整的滚动。会滚动到特定位置。
对于轴数的理解,我理解为,假设二位数组a[0轴][1轴],三维数组就是a[0][1][2]轴。
下面例子是将2轴放到1轴前面,也就是1 2轴互换位置
a = np.arange(8).reshape(2,2,2)
print(a[0,0,1])
print(a[0,1,0])
b=np.rollaxis(a,2,1)
print(b[0,0,1])
print(b[0,1,0])
1
2
2
1
④swapaxes
numpy.swapaxes 函数用于交换数组的两个轴
a = np.arange(8).reshape(2,2,2)
print(a[0,0,1])
print(a[1,0,0])
b=np.swapaxes(a,2,0)
print(b[0,0,1])
print(b[1,0,0])
1
4
4
1
3.修改数组维度
①broadcast
numpy.broadcast 用于模仿广播的对象,它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果
x = np.array([[1], [2], [3]])
y = np.array([4, 5, 6])
a = np.broadcast(x,y)
print(type(a))
b = np.zeros(a.shape,dtype=np.int8)
print(b)
print (x + y)
<class 'numpy.broadcast'>
[[0 0 0]
[0 0 0]
[0 0 0]]
[[5 6 7]
[6 7 8]
[7 8 9]]
②broadcast_to
broadcast_to 函数将数组广播到新形状。它在原始数组上返回只读视图。 它通常不连续。 如果新形状不符合 NumPy 的广播规则,该函数可能会抛出ValueError。
a = np.arange(4).reshape(1,4)
print (a)
print ('--------')
print (np.broadcast_to(a,(4,Python---NumPy模块