NumPy初学习

简介

NumPy (Numerical Python) 是一个开源 Python 库,广泛用于科学和工程领域。NumPy 库包含多维数组数据结构,例如同构的 N 维 ndarray,以及一个对这些数据结构有效操作的大型函数库。

ndarray 属性

ndim 维度

import numpy as np
import matplotlib.pyplot as plt
a = plt.imread('image.jpg')
print(a.ndim)
# output: 3 表示该数据有三个维度

shape 形状

print(a.shape)
# output: (549, 549, 3) 三维数据 分别表示宽度 高度 通道数

size 总长度

print(a.size)
# output: 904203 总数据量 各维数据量相乘

dtype 元素类型

print(a.dtype)
# output: uint8

itemsize 每个元素所占字节数

print(a.itemsize)
# output: 4

nbytes 总占用字节数

print(a.nbytes)
# output: 24

创建 ndarray 数组

numpy.array

numpy.array(list)

参数说明:

  • list为python列表

注意:

  • numpy默认ndarray中的所有元素类型是相同的

  • 若参入的列表中包含不同的参数类型,会自动统一为相同类型,优先级:str > float > int

  • ndarray中常见的数据类型:int、float、str等

    int:包含int8、uint8、int16、int32、int64

    float:包含float16、float32、float64

    str:字符串


numpy.ones

创建一个所有元素都为1的多维数组

numpy.ones(shape, dtype=None, order='C')

参数说明:

  • shape:形状
  • dtype=None:元素类型
  • order:{’C’, ‘F’ }可选,默认’C’在内存中以行优先存储,’F’列优先存储多维数据

numpy.zeros

创建一个所有元素都为1的多维数组

numpy.zeros(shape, dtype=None, order='C')

The parameters are as the numpy.ones.

numpy.full

创建一个所有元素都为指定元素的多维数组

numpy.full(shape, fill_value, dtype=None, order='C')

参数解释:

  • fil_value:填充值

numpy.eye

创建一个单位矩阵(对角线为1其他位置为0的二维数组)

numpy.eye(N, M=None, k=0, dtype=float)

参数说明:

  • N:行数
  • M:列数,默认为None,表示与行数相同
  • k=0:向右偏移0个位置
  • dtype:默认为float类型

code demo

import numpy as np
a = np.eye(3, 4, k=1)
print(a)
"""output: [[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
"""

numpy.linsapce

创建一个等差数列

numpy.linspace(start, stop, num=50, endpoint=True, restep=False, dtyp=None)

参数说明:

  • start:开始值
  • stop:结束值
  • num=50:等差数列中默认有50个值
  • endpoint=True:是否包含结束值
  • retstep=False:是否返回步长(公比)

code demo

import numpy as np
a = np.linspace(0,100,num=10, dtype=np.int64,retstep=True)
print(a)
"""output: (array([ 0, 11, 22, 33, 44, 55, 66, 77, 88, 100]), np.float64(11.11111111111111))
"""

numpy.arange

创建一个数值范围的数组

numpy.arange(start, stop, step, dtype)

参数说明:

  • start:开始值(可选)
  • stop:结束值(开区间)
  • step:步长(可选)

code demo

import numpy as np
a = np.arange(0,21,4)
print(a)
# output: [ 0 4 8 12 16 20]

numpy.random.randint

创建指定形状的随机整数数组

numpy.random.randint(low, high=None, size=None, dtype=None)

参数说明:

  • low:最小值
  • high=None:最大值 当high=None时生成的数值范围在[0,low)区间 high不为None时生成的数值范围在[low,high)区间
  • size=None:数组形状,默认生成一个随机数

code demo

import numpy as np
a = np.random.randint(1,100,size=(3,3),dtype=np.int32)
print(a)
""" output: [[77 28 31]
[71 53 96]
[97 87 88]]
"""

numpy.random.randn

创建一个服从标准正态分布的多维数组

标准正态分布又称u分布,是以0为均值,1为标准差的正态分布

numpy.random.randn(d0,d1,d2...,dn)

参数说明:

  • dn:第n个维度的数值

code demo

import numpy as np
a = np.random.randn()
print(a)
# output: -0.4698601267358489
b = np.random.randn(3)
print(b)
# output: [ 0.08159796 -0.10150956 -0.53101614]
c = np.random.randn(2,2)
print(c)
# output: [[-1.20232497 0.29635159]
# [-0.10822881 0.06725846]]

numpy.random.normal

创建一个服从正态分布的多维数组

numpy.random.normal(loc=0.0, scale=1.0, size=None)

参数解释:

  • loc=0.0:均值,对应正态分布的中心
  • scale:标准差,对应分布的宽度,scale越大正态分布的曲线越矮胖,scale越小曲线月高瘦
  • size=None:数组形状

code demo

import numpy as np
a = np.random.normal(loc=0, scale=5, size=(2,2))
print(a)
""" output: [[-6.5229379 -0.45689675]
[-9.8353663 -2.73223837]]
"""

numpy.random.random 与 numpy.random.rand

创建一个元素为0-1(左闭右开)随机数的多维数组

numpy.random.random(size=None)
numpy.random.rand(d0,d1,d2...,dn)

code demo

import numpy as np
a = np.random.random(5)
print(a)
# [0.44990641 0.20258517 0.71146886 0.76720135 0.71894741]
import numpy as np
b = np.random.rand(2)
print(b)
# [0.86621814 0.48620401]

NumPy 的基本操作

索引

与Python的索引一致

import numpy as np
# one-dimension array
a = np.array([1,2,3,4,5,6])
print(a[0],a[1])
# output: 1 2
# two-dimension array
b = np.random.randint(1,21,size=(3,3))
print(b)
"""output: [[ 8 20 17]
[ 9 6 11]
[ 6 1 16]]
"""
print(b[0])
# [ 8 20 17]
print(b[1][2]) # 也可写作 b[1,2]
# output: 11

切片

切片操作也类似于Python的切片操作

import numpy as np
a = np.array([1,2,3,4,5,6])
print(a[2:5])
# output: [3 4 5]

行操作

import numpy as np
m = np.random.randint(0,101,size=(5,5))
print(m)
"""output: [[53 0 31 61 7]
[72 8 73 47 16]
[56 96 71 5 12]
[34 69 13 81 23]
[84 16 19 57 29]]
"""
#取一行
print(m[0])
# output: [53 0 31 61 7]

# 取连续多行
print(m[1:3])
""" output: [[72 8 73 47 16]
[56 96 71 5 12]]
"""

#取不连续多行
print(m[[1,3,4]])
""" output: [[72 8 73 47 16]
[34 69 13 81 23]
[84 16 19 57 29]]
"""

列操作

# 取一列
print(m[ : , 0])
# output: [53 72 56 34 84]

# 取连续多列
print(m[ : , 1:5])
"""
output: [[ 0 31 61 7]
[ 8 73 47 16]
[96 71 5 12]
[69 13 81 23]
[16 19 57 29]]
"""

# 取不连续多列
print(m[:,[1,2,4]])
"""
output: [[ 0 31 7]
[ 8 73 16]
[96 71 12]
[69 13 23]
[16 19 29]]
"""

code demo

import numpy as np
import matplotlib.pyplot as plt
a = plt.imread('image.jpg')
plt.imshow(a)

image.png

# 行翻转 上下翻转
plt.imshow(a[::-1])

image.png

# 列翻转 左右翻转
plt.imshow(a[:,::-1])

image.png

# 第三维度翻转 颜色通道翻转 RGB -> BGR
plt.imshow(a[:,:,::-1])

image.png

# 模糊处理 每隔10个像素点去一个 相当于整体像素点变少 图片变模糊
plt.imshow(a[::10,::10])

image.png

变形

使用reshape函数对数组作变形

numpy.reshape(array, size, order='C')

参数解释:

  • array:原数组
  • size:重塑的形状

code demo

import numpy as np
n = np.random.randint(0,21,size=(3,4))
print(n)
""" output: [[ 6 8 19 20]
[15 18 15 16]
[16 5 3 12]]
"""

m = np.reshape(n, (4,3))
print(m)
""" output: [[ 6 8 19]
[20 15 18]
[15 16 16]
[ 5 3 12]]
"""
p = np.reshape(n, 12)
print(p)
# output: [ 6 8 19 20 15 18 15 16 16 5 3 12]

# -1的使用:自动匹配任意长度
q = np.reshape(n,(-1,2))
print(q)
"""output: [[ 6 8]
[19 20]
[15 18]
[15 16]
[16 5]
[ 3 12]]
表示固定列数为2,让计算机自己计算在元素总数不变的情况下,行数为多少(-1即为计算机计算出的行数,此处为6行)
"""

注意:变形前后数组中总个数相同

级联

所谓级联就是将多个数组合并

numpy.concatenate()

参数说明:

  • 参数必须为列表或元组(就是说要将合并的数组放在一个元组或列表中作为参数)
  • 级联的数组维度必须相同
  • 可以通过axis参数改变级联的方向

code demo

import numpy as np
n1 = np.random.randint(0,21,size=(3,2))
n2 = np.random.randint(0,11,size=(3,2))
n3 = np.concatenate([n1,n2])
print(n3)
"""output: [[ 2 12]
[15 12]
[10 14]
[ 2 3]
[ 7 2]
[ 3 5]]
"""
n4 = np.concatenate((n1,n2),axis=1)
print(n4)
"""output: [[ 2 12 2 3]
[15 12 7 2]
[10 14 3 5]]
"""

默认的级联方向是*axis=0*

水平级联

numpy.hstack

垂直级联

numpy.vstack

切分 / 拆分 / 分割

这三个函数都是级联的反向操作

numpy.split(ary, indices_or_sections, axis=0)

参数说明:

  • ary:表示要分割的数组
  • indices_or_sections:如果输入的是一个整数数值,则代表均分成该整数份,如果输入的是一维数组,则表示沿给定轴的索引位置进行分割
  • axis:指定分割方向

code demo

import numpy as np
a = np.random.randint(0,101,size=(4,4))
print(a)
""" output: [[27 51 25 18]
[ 7 13 13 87]
[29 59 3 75]
[ 9 19 61 37]]
"""
print(np.split(a,4)) # 默认拆分按照axis=0的方向
"""output: [array([[27, 51, 25, 18]], dtype=int32),
array([[ 7, 13, 13, 87]], dtype=int32),
array([[29, 59, 3, 75]], dtype=int32),
array([[ 9, 19, 61, 37]], dtype=int32)]
"""
print(np.split(a,4,axis=1))
"""output: [array([[27],
[ 7],
[29],
[ 9]], dtype=int32), array([[51],
[13],
[59],
[19]], dtype=int32), array([[25],
[13],
[ 3],
[61]], dtype=int32), array([[18],
[87],
[75],
[37]], dtype=int32)]
"""
# 垂直拆分
numpy.vsplit
# 水平拆分
numpy.hsplit

副本 / 拷贝 / 复制

copy()函数创建数组副本

numpy.copy(a, order='C')

注意:a 是待拷贝的母数组 拷贝操作是创建了一个副本 修改副本中的值不会影响母数组 需与赋值区分辨析

code demo

import numpy as np
a = np.arange(10)
b = np.copy(a) # 或写作 b=a.copy()
b[0] = 100
display(a, b)
""" output: a :array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
b: array([100, 1, 2, 3, 4, 5, 6, 7, 8, 9])
"""

NumPy 聚合操作

1. 求和

numpy.sum(ary, axis=None) # ary表示数组
  • *ary* 为一维数组,则求和为所有元素的和
  • *ary* 为二维数组,且无其他参数,则求和为所有元素之和;若有*axis*参数,*axis=0* 表示按列方向求和,*axis=1* 表示按行方向求和。

2. 最大值与最小值

numpy.max(ary, axis=None)
numpy.min(ary, axis=None)

3. 平均值

numpy.average(ary, axis=None)
numpy.mean(ary, axis=None)

4. 中位数

numpy.median(ary, axis=None)

5. 标准差

numpy.std(ary)

6. 方差

numpy.var(ary)

7. 返回最小元素索引

numpy.argmin(ary)

8. 返回最大元素索引

numpy.argmax(ary)

矩阵操作

基本操作

  • 创建矩阵
numpy.matrix(ary) # ary 为数组
numpy.array(ary)

算术运算

  • 矩阵与标量运算

无论是加减乘除,当与矩阵进行运算的值为标量时,其结果为矩阵中的每一个元素与该标量运算的结果。

code demo

import numpy as np
a = np.arange(0,11)
print(a)
# output: [ 0 1 2 3 4 5 6 7 8 9 10]

print(a + 1)
print(a - 1)
print(a * 2)
print(a / 2)
"""
output:
[ 1 2 3 4 5 6 7 8 9 10 11]
[-1 0 1 2 3 4 5 6 7 8 9]
[ 0 2 4 6 8 10 12 14 16 18 20]
[0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. ]
"""
  • 矩阵与矩阵运算

加减运算:

两个(或多个)矩阵相加减,运算结果仍为矩阵,将对应位置的元素相加减即可

code demo

import numpy as np
a = np.random.randint(0,11,size=(2,3))
b = np.random.randint(0,21,size=(2,3))
print(a)
print(b)
"""
output:
[[9 6 2]
[8 4 1]]
[[ 2 4 11]
[ 7 4 2]]
"""

print(a + b)
print(a - b)

"""output:
[[11 10 13]
[15 8 3]]
[[ 7 2 -9]
[ 1 0 -1]]
"""

乘法运算:

  • 矩阵点乘:两形状相同的矩阵对应元素相乘 *numpy.multiply(a, b) or* *a * b*
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print(np.multiply(a,b))
print("----------")
print(a*b)
"""
output:
[[ 5 12]
[21 32]]
----------
[[ 5 12]
[21 32]]
"""
  • 矩阵叉乘:一个 a x b 的矩阵乘以 b x c 的矩阵得到一个 a x c的矩阵 *numpy.dot(a, b) or a @ b*
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print(a@b)
print("------")
print(np.dot(a,b))
"""
output:
[[19 22]
[43 50]]
------
[[19 22]
[43 50]]
"""
  • 其他矩阵操作

矩阵转置:矩阵的转置是将矩阵的行和列互换 矩阵转置前后值相等

import numpy as np
a = np.matrix([[1,2,3],[4,5,6]])
print(a)
print(a.T)
"""
output:[[1 2 3]
[4 5 6]]

[[1 4]
[2 5]
[3 6]]

"""

向量操作

  • 向量点乘(内积)

两向量点乘(形状相同)得到一个标量 即逐元素相乘再相加*numpy.dot(a,b) or a@b*

import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])
print(a@b)
print(np.dot(a,b))
""" output:32
32
"""
  • 向量逐元素相乘

*numpy.multiply(a,b) or a*b*

import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])
print(a*b)
print(np.multiply(a,b))
"""
output:
[ 4 10 18]
[ 4 10 18]

"""
  • 向量外积(向量积或叉积)

即两个向量的法向量 *numpy.cross(a,b)*

import numpy as np
a = np.array([1,2,3])
b = np.array([3,4,5])
print(np.cross(a,b))
"""
output:
[-2 4 -2]
"""

矩阵的高级操作

  • 矩阵的逆

矩阵的逆对方阵(行数与列数相同的矩阵)定义,使用 numpy.linalg.inv() 可以计算矩阵的逆。

import numpy as np
a = np.random.randint(0,21,(3,3))
print(a)
print("a矩阵的逆为:\n",np.linalg.inv(a))
"""
output:
[[ 8 13 16]
[ 6 12 10]
[12 9 16]]
a矩阵的逆为:
[[-0.32692308 0.20512821 0.19871795]
[-0.07692308 0.20512821 -0.05128205]
[ 0.28846154 -0.26923077 -0.05769231]]
"""
  • 矩阵的行列式

行列式是标量值,表示矩阵的某些属性(如是否可逆)。使用*numpy.linalg.det()*计算矩阵的行列式

import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

print(np.linalg.det(a))
print(np.linalg.det(b))
"""
output:
a的行列式值为: -2.0000000000000004
b的行列式值为: -2.000000000000005
"""
  • 矩阵的迹

矩阵的迹是矩阵主对角线上元素的和,使用 numpy.trace() 可以计算

import numpy as np
a = np.array([[1,2],[3,4]])
print(np.trace(a))
# output: 5
  • 矩阵的特征值和特征向量

特征值和特征向量是方阵的重要属性,可以使用*numpy.linalg.eig()* 函数来计算特征值和特征向量

import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
value, vector = np.linalg.eig(a)
print("矩阵的特征值是:",value)
print("矩阵的特征向量是:",vector)
"""
output:
矩阵的特征值是: [ 1.61168440e+01 -1.11684397e+00 -1.30367773e-15]
矩阵的特征向量是: [[-0.23197069 -0.78583024 0.40824829]
[-0.52532209 -0.08675134 -0.81649658]
[-0.8186735 0.61232756 0.40824829]]
"""
  • 矩阵的广义逆

广义逆矩阵(Moore-Penrose伪逆)用于非方阵或不可逆的矩阵。使用*numpy.linalg.pinv()* 计算矩阵的广义逆

import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print(np.linalg.pinv(a))
"""
output:
[[-0.94444444 0.44444444]
[-0.11111111 0.11111111]
[ 0.72222222 -0.22222222]]
"""
  • 矩阵的范数

矩阵的范数用于度量矩阵的大小。可以使用*numpy.linalg.norm()* 计算不同类型的范数

import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])

print("矩阵a的二范数(默认,矩阵的二范数是其所有元素平方和的平方根)为:",np.linalg.norm(a))
print("矩阵b的1范数为(列和的最大值):",np.linalg.norm(b,ord=1))
print("矩阵b的无穷范数(行和的最大值):",np.linalg.norm(b,ord=np.inf))
"""
output:
矩阵a的二范数(默认,矩阵的二范数是其所有元素平方和的平方根)为: 5.477225575051661
矩阵b的1范数为(列和的最大值): 14.0
矩阵b的无穷范数(行和的最大值): 15.0
"""

广播机制

广播机制允许对不同形状的矩阵执行逐元素操作, NumPy 会自动扩展较小的数组以匹配较大的数组进行计算,使矩阵运算更加高效和便捷

广播机制的规则:

  • 为确实的维度补充维度
  • 缺失元素用已有值填充
import numpy as np
a = np.array([[1,2,3],[4,5,6]]) # 2 x 3 matrix
b = np.array([10,20,30]) # 1 x3 matrix

print("广播后矩阵相加结果为:", a+b)
"""
output:
广播后矩阵相加结果为: [[11 22 33]
[14 25 36]]
"""

其他常用数学操作

*abs sqrt square exp log sin cos tan round(ary, n) n为保留小数位 ceil floor cumsum*

import numpy as np
n = np.array([1.1,2.2,3.3,4.4])

print("a的绝对值:",np.abs(n)) # 绝对值
print("a的平方根:",np.sqrt(n)) # 平方根
print("a的平方:",np.square(n)) # 二次方
print("a的指数:",np.exp(n)) # 指数 e为底
print("a的指数:",np.log(n)) # 对数 e为底 以2为底 np.log2(n)
print("a的正弦值:",np.sin(n)) # 正弦
print(np.round(n)) # 四舍五入
print(np.ceil(n)) # 向上取整
print(np.floor(n)) # 向下取整
print(np.cumsum(n)) # 累计求和

"""
output:
a的绝对值: [1.1 2.2 3.3 4.4]
a的平方根: [1.04880885 1.4832397 1.81659021 2.0976177 ]
a的平方: [ 1.21 4.84 10.89 19.36]
a的指数: [ 3.00416602 9.0250135 27.11263892 81.45086866]
a的指数: [0.09531018 0.78845736 1.19392247 1.48160454]
a的正弦值: [ 0.89120736 0.8084964 -0.15774569 -0.95160207]
[1. 2. 3. 4.]
[2. 3. 4. 5.]
[1. 2. 3. 4.]
[ 1.1 3.3 6.6 11. ]
"""

ndarray 排序

快速排序 *numpy.sort() and ndarray.sort()*

  • *numpy.sort(array)* 不改变原数组,会开辟新的空间存储排序后的数组
  • *ndarray.sort(array)* 排序后的数组占用原数组的空间,不开辟新的空间
import numpy as np
a = np.random.randint(0,50,10)
b = np.sort(a)
print("Sorted array:",b)
print("Original array:",a)
"""
output:
Sorted array: [12 20 21 23 25 30 33 38 40 47]
Original array: [38 40 47 23 30 20 12 33 25 21]
"""

c = a.sort()
print("Sorted Array:", c)
print("Original Array:", a)
"""
output:
Sorted Array: None
Original Array: [12 20 21 23 25 30 33 38 40 47]

Use ndarray.sort(), it will change the original array,so c is None.
"""