系列文章目录
提示:仅记录个人的学习心得,欢迎交流
(占位,以后再补 ……………………)
前言
对python语言基础中记忆不牢的进行总结,希望自己能坚持下去!为了学习计算机视觉做准备!
本次介绍本书第四章的内容Numpy基础。
一、NumPy基础
1.1 ndarray基础
一个ndarrary是一个通用的多维同类数据容器。每个元素在内存中有相同的存储空间。
几个属性:①shape:用来表征数组的规模
②dtype:描述数组的数据类型
③stride:前进到当前维度下一个元素需要"跨过"的字节数(必须是整数!)
④itemsize: 对象中每个元素的大小,以字节为单位
⑤size:数组元素的总个数
创建ndarray的常用方法:
array()函数接收序列型的对象返回ndarray数组
对于嵌套序列,例如等长度的列表会自动转换成多维数组。
对于不等长的嵌套数组会转换成object类型。
import numpy as np
arr1 = [[1, 2, 3, 4, ],[5, 6, 7, 8]]
arr2 = np.asarray(arr1)
print(arr2)
>>> [[1 2 3 4]
[5 6 7 8]]
print(arr2.dtype)
>>> int32
import numpy as np
arr1 = [[1, 2, 3, 4, ],[5, 6, 7]]
arr2 = np.asarray(arr1,dtype=object) # 如果不加dtype=object编译会警告
print(arr2)
>>> [list([1, 2, 3, 4]) list([5, 6, 7])]
print(arr2.dtype)
>>> object
astype函数可以显式的转换数组的数据类型(如果将浮点型转换成整型,小数部分会消除,不是四舍五入!),转换错误时会抛出ValueError错误。
ndarray数组的优势就是对元素进行操作不需要用到for循环,在等尺寸的数组之间的算术操作都应用了逐元素操作的方式,这种特性成为向量化。不同尺寸数组之间的操作会用到广播特性。
1.2 ndarray数组的索引与切片
arr1 = np.arange(10)
>>> [0 1 2 3 4 5 6 7 8 9]
arr1[5]
>>> 5
arr1[5:8] = 12
arr1
>>> [ 0 1 2 3 4 12 12 12 8 9]
区别于python的内建列表,数组的切片是原数组的视图,任何对视图的修改都会反映到原数组上。
如果想得到拷贝而不是原视图的话,要显式的用到copy函数。例如:arr2 = arr[5:8].copy()
arr1 = [ 0 1 2 3 4 12 12 12 8 9]
arr_slice = arr1[5:8]
print(arr_slice)
>>> [12 12 12]
arr_slice[1] = 12345
print(arr1)
>>> [ 0 1 2 3 4 12 12345 12 8 9]
在二维数组中,索引值对应的元素一个值,而是一个一维数组;单个元素可以通过递归的方式获得
对于更高维的数组,可以省略后续的索引值,获得不同维度的切片。
arr2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2[2]
>>> [7 8 9]
arr2[0][2]
>>> 3
arr2[0, 2]
>>> 3
所有切片的下标都是从0开始的,包前不包后!!!
1.2.1布尔索引:用逻辑表达式来描述索引;布尔值数组长度必须和数组轴索引长度一致。
布尔索引选择出的数据总是生成数据的拷贝,原数据并无任何变化。
注意:用来进行判断的数组即布尔值数组也必须是ndarray数组
同样的方法也可以选择列数据,选择的时候行索引用 " : " 占位就好了
import numpy as np
arr_2D = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr_bool = np.array(['bob', 'joe', 'will'])
arr1 = arr_2D[arr_bool == 'bob']
print(arr1)
>>> [[1 2 3]]
arr_2D = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr_2D[arr_2D < 5] = 0
print(arr_2D)
>>> [[0 0 0]
[0 5 6]
[7 8 9]]
1.2.2 神奇索引:用整数数组进行数据索引
例如:arr[[4, 5, 0, 6]] 会选择arr数组中第5,6,1,7行的数据
倒数第3,5,7行的数据
神奇索引和切片不同,总是将数据复制到一个新的数组
神奇索引的误区 ⬇⬇⬇⬇⬇
我们可能以为形式1会得到形式2的结果,而形式1相当于秩为2的矩阵选择数据;形式2才可以看成两次神奇索引选择,实际上形式2也可以分开写!
import numpy as np
arr = np.arange(32).reshape((8, 4))
print(arr)
>>> [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]
[24 25 26 27]
[28 29 30 31]]
print(arr[[1, 5, 7, 2], [0, 3, 1, 2]]) # 形式1
>>> [ 4 23 29 10]
print(arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]) # 形式2
>>> [[ 4 7 5 6]
[20 23 21 22]
[28 31 29 30]
[ 8 11 9 10]]