复习python时的记录
NumPy
支持大量的维度数组与矩阵运算,也针对数组运算提供大量的数学函数库
1、 Ndarray 对象:用于存放同类型元素的多维数组
① 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
a = np.array([1, 2, 3, 4, 5], ndmin = 2)
print (a) #[[1 2 3 4 5]]
② numpy.dtype(object, align, copy) 获取dtype类型
- object 数据类型对象
- align 如果为 true,填充字段使其类似 C 的结构体。
- copy 复制 dtype 对象 ,如果为 false,则是对内置数据类型对象的引用
# int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替
import numpy as np
# 字节顺序标注
dt = np.dtype('<i4')
print(dt) #int32
dt = np.dtype([('age',np.int8)])
print(dt) # [('age', 'i1')]
# 将数据类型应用于 ndarray 对象
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student)
print(a) # [('abc', 21, 50.0), ('xyz', 18, 75.0)]
符号 | 解释 |
---|---|
b | 布尔型 |
i | (有符号) 整型 |
u | 无符号整型 integer |
f | 浮点型 |
c | 复数浮点型 |
m | timedelta(时间间隔) |
M | datetime(日期时间) |
O | (Python) 对象 |
S, a | (byte-)字符串 |
U | Unicode |
V | 原始数据 (void) |
注:字节顺序是通过对数据类型预先设定 < 或 > 来决定的。 < 意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。> 意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)
2、数组属性
属性 | 解释 |
---|---|
ndarray.ndim | 数组的秩(rank),即数组的维度数量或轴的数量 |
ndarray.shape | 返回一个元组,数组的维度,表示数组在每个轴上的大小。对于二维数组(矩阵),表示其行数和列数 |
ndarray.size | 数组中元素的总个数,等于 ndarray.shape 中各个轴上大小的乘积 |
ndarray.dtype | 数组中元素的数据类型 |
ndarray.itemsize | 数组中每个元素的大小,以字节为单位 |
ndarray.flags | 包含有关内存布局的信息,如是否为 C 或 Fortran 连续存储,是否为只读等 |
ndarray.real | 数组中每个元素的实部(如果元素类型为复数) |
ndarray.imag | 数组中每个元素的虚部(如果元素类型为复数) |
ndarray.data | 实际存储数组元素的缓冲区,一般通过索引访问元素,不直接使用该属性 |
① 调整数组大小
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print (a.shape) # (2, 3)
# 通过shape属性调整
a.shape = (3,2)
print (a) #[[1 2] [3 4] [5 6]]
# 通过reshape函数调整
b = a.reshape(3,2)
print (b)#[[1 2] [3 4] [5 6]]
② 切片:冒号分隔切片参数 start:stop:step 来进行切片操作
import numpy as np
a = np.arange(10)
s = slice(2,7,2) # 从索引 2 开始到索引 7 停止,间隔为2
print (a[s])
b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2
③ 索引:
(1)整数索引:
import numpy as np
x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0,1,2], [0,1,0]]
print (y) #获取数组中 (0,0),(1,1) 和 (2,0) 位置处的元素
rows = np.array([[0,0],[2,2]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols] #获取数组中 (0,0),(0,2),(2,0) 和 (2,2) 位置处的元素
y = x[1:2, 1:2] #[[1, 2], [3, 4]]
x=np.arange(32).reshape((8,4))
print (x[[4,2,1,7]]) # 二维数组读取指定下标对应的行
print (x[[-4,-2,-1,-7]])
(2)布尔索引:
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print (x[x > 5]) # 打印出大于 5 的元素 [ 6 7 8 9 10 11]
a = np.array([np.nan, 1,2,np.nan,3,4,5])
print (a[~np.isnan(a)]) #过滤nan
(3)索引数组:
import numpy as np
x=np.arange(32).reshape((8,4))
print (x[np.ix_([1,5,7,2],[0,3,1,2])]) #[(1,0),(1,3),(1,1),(1,2),(5,0),...,(2,2)]
np.ix_ 函数就是输入两个数组,产生笛卡尔积的映射关系。笛卡尔乘积是指在数学中,两个集合 X 和 Y 的笛卡尔积(Cartesian product),又称直积,表示为 X×Y,第一个对象是X的成员而第二个对象是 Y 的所有可能有序对的其中一个成员
3、创建数组
① numpy.empty(shape, dtype = float, order = ‘C’) :创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组,order有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。其中数组元素为随机值,因为它们未初始化
import numpy as np
x = np.empty([3,2], dtype = int)
print (x)
#[[ 6917529027641081856 5764616291768666155]
# [ 6917529027641081859 -5764598754299804209]
# [ 4497473538 844429428932120]]
② numpy.zeros(shape, dtype = float, order = ‘C’):创建指定大小的数组,数组元素以 0 来填充
③ numpy.ones(shape, dtype = None, order = ‘C’):创建指定形状的数组,数组元素以 1 来填充
④ numpy.zeros_like(a, dtype=None, order=‘K’, subok=True, shape=None):创建一个与给定数组a具有相同形状的数组,数组元素以 0 来填充
⑤ numpy.ones_like(a, dtype=None, order=‘K’, subok=True, shape=None):创建一个与给定数组a具有相同形状的数组,数组元素以 1 来填充
⑥ numpy.asarray(a, dtype = None, order = None):类似 numpy.array,从已有的数组创建数组
⑦ numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0):用于实现动态数组
⑧ numpy.fromiter(iterable, dtype, count=-1):从可迭代对象中建立 ndarray 对象,返回一维数组
⑨ numpy.arange(start, stop, step, dtype):使用 arange 函数创建数值范围并返回 ndarray 对象,根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray
⑩ np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):用于创建一个一维数组,数组是一个等差数列构成的,endpoint值为 true 时,数列中包含stop值,反之不包含,默认是True。
import numpy as np
a = np.linspace(10, 20, 5, endpoint = False)
print(a) #[10. 12. 14. 16. 18.]
① np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None):创建一个于等比数列,取对数的时候
import numpy as np
# 默认底数是 10
a = np.logspace(1.0, 2.0, num = 10)
print (a)
#[ 10. 12.91549665 16.68100537 21.5443469 27.82559402
# 35.93813664 46.41588834 59.94842503 77.42636827 100. ]
4、广播
如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘;当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。
广播机制:让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。输出数组的形状是输入数组形状的各个维度上的最大值
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([0,1,2])
print(a + b) # [[ 0 1 2] [10 11 12] [20 21 22] [30 31 32]]
5、迭代
迭代器对象 numpy.nditer()
① 参数:风格对象
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
b = a.T #转置
for x in np.nditer(b.copy(order='C')): #以C的风格排序
print (x, end=", " ) # 0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,
for x in np.nditer(b.copy(order='F')): #以F的风格排序
print (x, end=", " ) #0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,
② 参数:op_flags,默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值的修改,可以设置为readwrite 或者 writeonly 的模式
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print (a) #[[ 0 10 20 30] [ 40 50 60 70] [ 80 90 100 110]]
③ 广播迭代:如果两个数组是可广播的,nditer 组合对象能够同时迭代它们,数组 b 被广播到 a 的大小
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
b = np.array([1, 2, 3, 4], dtype = int)
for x,y in np.nditer([a,b]):
print ("%d:%d" % (x,y), end=", " )
# 0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,
④numpy.ndarray.flat 是一个数组元素迭代器
import numpy as np
a = np.arange(9).reshape(3,3)
#对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
for element in a.flat:
print (element)
6、数组操作
① 元素的添加与删除
(1)numpy.resize(arr, shape):返回指定大小的新数组
b = np.resize(a, (3,2))
(2)numpy.append(arr, values, axis=None):在数组的末尾添加值
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print ('向数组添加元素:')
print (np.append(a, [7,8,9])) #[1 2 3 4 5 6 7 8 9]
print (np.append(a, [[7,8,9]],axis = 0)) #[[1 2 3] [4 5 6] [7 8 9]]
print (np.append(a, [[5,5,5],[7,8,9]],axis = 1)) #[[1 2 3 5 5 5] [4 5 6 7 8 9]]
(3)numpy.insert(arr, obj, values, axis):在给定索引之前,沿给定轴在输入数组中插入值
import numpy as np
a = np.array([[1,2],[3,4],[5,6]])
print (np.insert(a,3,[11,12])) #[ 1 2 3 11 12 4 5 6]
print ('沿轴 0 广播:')
print (np.insert(a,1,[11],axis = 0)) #[[ 1 2] [11 11] [ 3 4] [ 5 6]]
print ('沿轴 1 广播:')
print (np.insert(a,1,11,axis = 1)) #[[ 1 11 2] [ 3 11 4] [ 5 11 6]]
(4)numpy.delete(arr, obj, axis):从输入数组中删除指定子数组的新数组,如果未提供轴参数,则输入数组将展开
import numpy as np
a = np.arange(12).reshape(3,4)
print (np.delete(a,5)) #[ 0 1 2 3 4 6 7 8 9 10 11]
print (np.delete(a,1,axis = 1)) #[[ 0 2 3] [ 4 6 7] [ 8 10 11]]
a = np.array([1,2,3,4,5,6,7,8,9,10])
print (np.delete(a, np.s_[::2])) #[ 2 4 6 8 10]
(5)numpy.unique(arr, return_index, return_inverse, return_counts):去除数组中的重复元素
- return_index:如果为true,返回新列表元素在旧列表中的位置(下标),并以列表形式储
- return_inverse:如果为true,返回旧列表元素在新列表中的位置(下标),并以列表形式储
- return_counts:如果为true,返回去重数组中的元素在原数组中的出现次数
import numpy as np
a = np.array([5,2,6,2,7,5,6,8,2,9])
u = np.unique(a) #[2 5 6 7 8 9]
u,indices = np.unique(a, return_index = True) # [1 0 2 4 7 9]
u,indices = np.unique(a,return_inverse = True) # [1 0 2 0 3 1 2 4 0 5]
u,indices = np.unique(a,return_counts = True) #[3 2 2 1 1 1]
② 修改形状
(1) numpy.reshape(arr, newshape, order=‘C’):修改数组形状
(2)ndarray.flatten(order=‘C’):展开数组,‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘K’ – 元素在内存中的出现顺序,修改不会影响原始数组
(3) numpy.ravel(a, order=‘C’):展平的数组元素,顺序通常是"C风格",返回的是数组视图,修改会影响原数组
(4) numpy.transpose(arr, axes):翻转数组的axes维度,axes:整数列表,对应维度,通常所有维度都会对换
(5) ndarray.T:翻转数组ndarray
(6) numpy.rollaxis(arr, axis, start):向后滚动特定的轴到一个特定位置
import numpy as np
# 创建了三维的 ndarray
a = np.arange(8).reshape(2,2,2)
# 将轴 2 滚动到轴 0(宽度到深度)
b = np.rollaxis(a,2,0)#[[[0 2] [4 6]] [[1 3] [5 7]]]
print(np.where(b==6)) #a[1,1,0],即 6 的坐标,变成 [0, 1, 1],最后一个 0 移动到最前面
# 将轴 2 滚动到轴 1:(宽度到高度)
c = np.rollaxis(a,2,1)#[[[0 2] [1 3]] [[4 6] [5 7]]]
print(np.where(c==6)) # 查看元素 a[1,1,0],即 6 的坐标,变成 [1, 0, 1],最后的 0 和 它前面的 1 对换位置
(7) numpy.swapaxes(arr, axis1, axis2):交换数组的两个轴
③ 改变维度
(1) numpy.broadcast(x,y) :广播
(2) numpy.broadcast_to(array, shape, subok):广播到新形状,返回视图
(3) numpy.expand_dims(arr, axis):在指定位置插入新的轴来扩展数组形状
(4) numpy.squeeze(arr, axis):给定数组的形状中删除一维的条目
④ 链接数组
(1) numpy.concatenate((a1, a2, …), axis):沿指定轴连接相同形状的两个或多个数组
(2) numpy.stack(arrays, axis):用于沿新轴连接数组序列
print (np.stack((a,b),0)) # 沿轴 0 堆叠两个数组
(3) numpy.hstack(arrays, axis):通过水平堆叠来生成数组
(4) numpy.vstack(arrays, axis):通过垂直堆叠来生成数组
⑤ 分割数组
(1)numpy.split(ary, indices_or_sections, axis):沿特定的轴将数组分割为子数组
import numpy as np
a = np.arange(9)
print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3) #[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7]) #[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
print('沿水平方向分割:') # hsplit
c = np.split(a,2,1)
#[array([[ 0, 1],[ 4, 5],[ 8, 9],[12, 13]]), array([[ 2, 3],[ 6, 7],[10, 11],[14, 15]])]
(2)numpy.hsplit:水平方向分割数组
(3)numpy.vsplit:垂直方向分割数组
⑥ 三角函数
(1)sin()、cos()、tan()
a = np.array([0,30,45,60,90])
# 通过乘 pi/180 转化为弧度
print (np.sin(a*np.pi/180))
(2)arcsin,arccos,和 arctan 函数返回给定角度的 sin,cos 和 tan 的反三角函数,函数的结果可以通过 numpy.degrees() 函数将弧度转换为角度
⑦ 四舍五入函数
(1)numpy.around() :返回指定数字的四舍五入值,decimals为舍入的小数位数
(2)numpy.floor() :返回小于或者等于指定表达式的最大整数,即向下取整
(3)numpy.ceil() :返回大于或者等于指定表达式的最小整数,即向上取整
⑧ 算术函数
(1)加减乘除: add(),subtract(),multiply() 和 divide()
(2)numpy.reciprocal() :返回参数逐元素的倒数。如 1/4 倒数为 4/1
(3)numpy.power() :将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂
(4)numpy.mod() :计算输入数组中相应元素的相除后的余数。 函数 numpy.remainder() 也产生相同的结果
⑨ 统计函数
(1)numpy.amin(a, axis=None, out=None, keepdims=, initial=, where=) :计算数组中的元素沿指定轴的最小值
(2)numpy.amax(a, axis=None, out=None, keepdims=, initial=, where=) :计算数组中的元素沿指定轴的最大值
(3)numpy.ptp(a, axis=None, out=None, keepdims=, initial=, where=) :计算数组中元素最大值与最小值的差(最大值 - 最小值)
- a: 输入的数组,可以是一个NumPy数组或类似数组的对象。
- axis: 可选参数,用于指定在哪个轴上计算最小值。如果不提供此参数,则返回整个数组的最小值。可以是一个整数表示轴的索引,也可以是一个元组表示多个轴。
- out: 可选参数,用于指定结果的存储位置。
- keepdims: 可选参数,如果为True,将保持结果数组的维度数目与输入数组相同。如果为False(默认值),则会去除计算后维度为1的轴。
- initial: 可选参数,用于指定一个初始值,然后在数组的元素上计算最小值。
- where: 可选参数,一个布尔数组,用于指定仅考虑满足条件的元素。
(4)numpy.percentile(a, q, axis):百分位数是统计中使用的度量,表示小于q的观察值的百分比
import numpy as np
a = np.array([[10, 7, 4], [3, 2, 1]])
# 50% 的分位数,就是 a 里排序之后的中位数
print (np.percentile(a, 50))
(5)numpy.median(a, axis=None, out=None, overwrite_input=False, keepdims=):计算中位数
(6)numpy.mean(a, axis=None, dtype=None, out=None, keepdims=):返回数组中元素的算术平均值
(7)numpy.average(a, axis=None, weights=None, returned=False):根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值
wts = np.array([4,3,2,1])
print (np.average(a,weights = wts))
(8)numpy.std([1,2,3,4]):计算标准差 sqrt(mean((x - x.mean())**2))
(9)numpy.var([1,2,3,4]):计算方差 mean((x - x.mean())** 2)
⑩排序筛选函数
(1)numpy.sort(a, axis, kind, order)
- axis: 沿着它排序数组的轴,如果没有数组会被展开,沿着最后的轴排序, axis=0 按列排序,axis=1 按行排序
- kind: 默认为’quicksort’(快速排序)‘quicksort’(快速排序)‘mergesort’(归并排序)‘heapsort’(堆排序)
- order: 如果数组包含字段,则是要排序的字段
import numpy as np
a = np.array([[3,7],[9,1]])
print (np.sort(a)) #[[3 7] [1 9]]
print (np.sort(a, axis = 0)) #按列排序 [[3 1] [9 7]]
# 在 sort 函数中排序字段
dt = np.dtype([('name', 'S10'),('age', int)])
a = np.array([("raju",21),("anil",25),("ravi", 17), ("amar",27)], dtype =
print (np.sort(a, order = 'name'))
(2)numpy.argsort() :返回的是数组值从小到大的索引值
x = np.array([3, 1, 2])
y = np.argsort(x) #[1 2 0]
(3)numpy.lexsort(keys, axis=None) :对多个序列进行排序,对给定的 keys 中的最后一个 key 排序
import numpy as np
a = [[3, 3, 8],
[6, 9, 7],
[3, 3, 2]]
b = np.array(a) # 转换为 numpy 数组
"""
index = np.lexsort((b[:, 2], b[:, 1], b[:, 0])) 的运行情况:
step-1、首先按照第一列 b[:, 0] 的数值 [3, 6, 3] 升序顺序对每行的位置进行重排, 第一行有两个值相同, 转到step-2
[[3, 3, 8], [[3, 3, 8],
[6, 9, 7], --> [3, 3, 2],
[3, 3, 2]] [6, 9, 7]]
step-2、第一列数值相同的情况下按照相应位置第二列 b[:, 1] 的值继续排序, 第二列对应位置任然相同, 转到step-3
[[3, 3, 8], [[3, 3, 8],
[6, 9, 7], --> [3, 3, 2],
[3, 3, 2]] [6, 9, 7]]
step-3、第二列数值相同的情况下按照相应位置第三列 b[:, 2] 的值继续排序
[[3, 3, 8], [[3, 3, 2],
[6, 9, 7], --> [3, 3, 8],
[3, 3, 2]] [6, 9, 7]]
总结: 第一列的排序结果为[3, 3, 6] 对应的索引值为 [2, 0, 1]
"""
index = np.lexsort((b[:, 2], b[:, 1], b[:, 0]))
print(index) # 输出结果: [2 0 1]
ans = b[index] # 按照排序结果重置数组元素的位置
print(ans)
# ans 的结果:
[[3 3 2]
[3 3 8]
[6 9 7]]
(4)numpy.argmax() 和 numpy.argmin():分别沿给定轴返回最大和最小元素的索引
(5)numpy.nonzero() :返回输入数组中非零元素的索引
import numpy as np
a = np.array([[30,40,0],[0,20,10],[50,0,60]])
print (np.nonzero (a)) #(array([0, 0, 1, 1, 2, 2]), array([0, 1, 1, 2, 0, 2]))
(6)numpy.where() :返回输入数组中满足给定条件的元素的索引
import numpy as np
x = np.arange(9.).reshape(3, 3)
y = np.where(x > 3) #(array([1, 1, 2, 2, 2]), array([1, 2, 0, 1, 2]))
(7)numpy.extract() :根据某个条件从数组中抽取元素,返回满条件的元素
import numpy as np
x = np.arange(9.).reshape(3, 3)
condition = np.mod(x,2) == 0 # 定义条件, 选择偶数元素
print (np.extract(condition, x)) #[0. 2. 4. 6. 8.]
⑪矩阵运算
(1)numpy.dot(a, b, out=None) :计算点积
(2)numpy.vdot(a,b) :两个向量的点积
(3)numpy.matmul :返回两个数组的矩阵乘积
(4)numpy.linalg.det() 函数计算输入矩阵的行列式,对于 2×2 矩阵,它是左上和右下元素的乘积与其他两个的乘积的差,对于矩阵[[a,b],[c,d]],行列式计算为 ad-bc
(5)numpy.linalg.inv() 函数计算矩阵的乘法逆矩阵
副本和视图
(1)副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置
(2)视图是数据的一个别称或引用,通过该别称或引用亦便可访问、操作原有数据,但原有数据不会产生拷贝。如果我们对视图进行修改,它会影响到原始数据,物理内存在同一位置
视图一般发生在:numpy 的切片操作返回原数据的视图、调用 ndarray 的 view() 函数产生一个视图
副本一般发生在:Python 序列的切片操作,调用deepCopy()函数、调用 ndarray 的 copy() 函数产生一个副本
参考
这儿