学习笔记-Numpy知识

学习笔记-Numpy知识

文章目录

Numpy介绍

NumPy 全名是 "Numerical Python",也就是"用于数值计算的 Python 库"。

普通 Python 当然也可以进行数学计算,但要是进行大量的向量计算、矩阵计算、机器学习数据处理,NumPy 会方便很多。

ndarray介绍

ndarray 是 Numpy 中最核心的数据结构,其可以理解成一个专门用于数学计算的高级数组。

python 复制代码
import numpy as np

a = np.array([1, 2, 3]) # 这里的操作就是把Python的列表转化为Numpy数组

print(a) # 输出[1 2 3]

为什么不直接使用 Python 列表?

Python列表不能直接用于计算,还需要转换,步骤繁琐,Numpy可以直接进行计算。

python 复制代码
# 直接在python中计算
a = [1, 2, 3]
a * 2 # 这里会输出[1, 2, 3, 1, 2, 3],因为"*"在python中是重复列表操作
python 复制代码
import numpy as np

a = np.array([1, 2, 3])

print(a * 2) # 这里会输出[2 4 6],可以直接对整个数组进行数学运算

Numpy中的多维数组

python 复制代码
# 一维 可以想象成 1 2 3
a = np.array([1, 2, 3])

"""
二维 可以想象成:
1 2 3 
4 5 6
"""
b = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

# 三维 可以想象成很多个二维矩阵一层一层堆叠起来
c = np.array([          
    [                   
        [1, 2],        
        [3, 4]
    ],
    [
        [5, 6],
        [7, 8]
    ]
])
shape属性
python 复制代码
import numpy as np

a = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

print(a.shape) # 输出(2, 3),这个数组有2 行、3 列

a = np.array([
    [1, 2],
    [3, 4],
    [5, 6]
])

print(a.shape) # 输出(3, 2),这个数组有3行、2列
ndim属性
python 复制代码
import numpy as np

a = np.array([1, 2, 3])

print(a.ndim) # 输出1,这个数组是1维的

a = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

print(a.ndim) # 输出2,这个数组是2维的
总结
属性 含义
shape 每个维度有多少个元素
ndim 有多少个维度

完整例子

python 复制代码
import numpy as np # 引入Numpy包

data = np.array([  # 创建Numpy数组
    [10, 20, 30],
    [40, 50, 60]
])

print(data)
print(data.shape) # 打印data数组每个维度的元素个数 输出(2,3)
print(data.ndim)  # 打印data数组的维度 输出2

result = data * 2 # 对data数组中所有元素进行乘2操作

print(result)

# 上述代码运行结果
[[10 20 30]
 [40 50 60]]

(2, 3)

2

[[ 20  40  60]
 [ 80 100 120]]

Numpy数组的创建

常用的几种创建方式

  • 使用np.array()创建:最常用的创建方式
python 复制代码
import numpy as np

a = np.array([1, 2, 3])

print(a) # 输出 [1 2 3]

a = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

print(a)
"""
输出
[[1 2 3]
 [4 5 6]]
"""
  • 使用np.zeros()创建:创建全0数组
python 复制代码
a = np.zeros(5) # 创建包含5个0的一维数组

print(a) # 输出[0. 0. 0. 0. 0.]

a = np.zeros((2, 3)) # 创建二维数组,第一维度有两个元素,第二维度有3个元素,第二维度的元素都为0

print(a)
"""
输出
[[0. 0. 0.]
 [0. 0. 0.]]
"""
  • 使用np.ones()创建:创建全1数组
python 复制代码
a = np.ones((2, 3)) # 此用法与zeros相似,只不过0全部变为1

print(a)
"""
输出
[[1. 1. 1.]
 [1. 1. 1.]]
"""
  • 使用np.arange()创建:创建连续数字数组
python 复制代码
a = np.arange(5) # 创建连续数组的数组 依旧遵循range左闭右开的原则

print(a) # 输出 [0 1 2 3 4]

np.arange(0, 10, 2) # 可以设置步长
print(a) # 输出 [0 2 4 6 8]

示例

python 复制代码
import numpy as np

a = np.zeros((2, 3)) # 创建全零的二维数组

b = np.ones((3, 2)) # 创建全1的二维数组

c = np.arange(2, 8, 2) # 创建1维的连续数字数组,数字从2开始到8结束,不包含8

Numpy索引与切片

一维数组索引

在Numpy中,一维数字索引与python中用法相同

python 复制代码
# 一维数字索引
import numpy as np

a = np.array([10, 20, 30, 40, 50])

print(a[0]) # 输出10
print(a[2]) # 输出20
print(a[4]) # 输出30

二维数组索引

python 复制代码
# 二维数字索引
a = np.array([
    [10, 20, 30],
    [40, 50, 60]
])

print(a[0,0]) # 输出10,代表的是第0行、第0列的元素
print(a[1,2]) # 输出60,代表的是第1行、第2列的元素

在Numpy中,"a0"代表的不是第一个数字,其意思为取第0行

python 复制代码
a = np.array([
    [10, 20, 30],
    [40, 50, 60]
])
print(a[0]) # 输出[10 20 30]
print(a[1]) # 输出[40 50 60]

一维数组切片

Numpy中的切片与python列表基本一致

python 复制代码
# 一维切片
a = np.array([10, 20, 30, 40, 50])

print(a[1:4]) # 输出[20 30 40],依旧遵循左闭右开的原则

二维数组切片

python 复制代码
# 二维数组切片
a = np.array([
    [10, 20, 30],
    [40, 50, 60],
    [70, 80, 90]
])
print(a[0:2]) # 这表示的含义是取第0行到第2行之前
"""
输出结果为:
[[10 20 30]
 [40 50 60]]
"""

":"的含义

在Numpy中,":"可以被理解为这一维全部取

python 复制代码
a = np.array([
    [10, 20, 30],
    [40, 50, 60],
    [70, 80, 90]
])

print(a[:,0]) # 表示取所有行的第0列,最后输出为[10 40 70]
print(a[:,1]) # 表示取所有行的第1列,最后输出为[20 50 80]
print(a[:,1:3]) # 表示取所有行的第1列到第3列之前
"""
a[:,1:3]最后输出为:
[[20 30]
 [50 60]
 [80 90]]
"""

数组中的Shape 和 Reshape

shape

shape用于输出数组每个维度有多少个元素

python 复制代码
import numpy as np

a = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

print(a.shape) # 输出(2,3) 表示2行3列,一共2*3个元素

reshape

reshape的意思为"改变数组的形状",reshape不会改变数据本身,数据没有增加,也没有减少,只是重新排列成了不同的形状。

python 复制代码
a = np.array([1, 2, 3, 4, 5, 6])

b = a.reshape(2, 3) # 将原来的一维数组变为二维数组

print(b)
"""
b的输出结果为:
[[1 2 3]
 [4 5 6]]
"""

遵循原则:reshape 前后,两个数组的元素总数量必须相同。

以上述内容为例,原数组为1 2 3 4 5 6,共有6个元素,这里就可以进行reshape(2,3),因为2*3=6,当然也可以reshape(3,2)

python 复制代码
import numpy as np

data = np.arange(1, 13) # 得到[1 2 3 4 5 6 7 8 9 10 11 12]

print(data) # 输出[1 2 3 4 5 6 7 8 9 10 11 12]

data = data.reshape(3, 4) # 利用reshape进行转换,转换为3行4列的数组

print(data)
"""
最后的输出结果为:
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
"""

Numpy中的数组运算

Numpy最强大的地方在于可以直接对数组进行数学运算, 其会把运算作用到每一个元素

python 复制代码
import numpy as np

a = np.array([1, 2, 3])

print(a + 10) # 整体元素全部加10 输出[11 12 13]
print(a * 2)  # 整体元素全部乘2  输出[2 4 6]
print(a - 1)  # 整体元素全部减1  输出[0 1 2]
print(a / 2)  # 整体元素全部除2  输出[0.5 1.  1.5]

a = np.array([
    [1, 2],
    [3, 4]
])

print(a * 2)
"""
输出结果为:
[[2 4]
 [6 8]]
"""

在Numpy中,两个数组也可以直接进行运算

python 复制代码
a = np.array([1, 2, 3])
b = np.array([10, 20, 30])

print(a + b) # 输出为[11 22 33]
print(a * b) # a*b不是矩阵乘法,是对应位置的元素分别相乘 输出为[10 40 90]

广播机制

python 复制代码
a = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

b = np.array([10, 20, 30])

print(a + b)
"""
Numpy自动把[10 20 30]广播到a的每一行,然后进行运算
输出结果为:
[[11 22 33]
 [14 25 36]]
"""

矩阵运算

在Numpy中,"*"与"@"完全不同,前者代表的是对应元素相乘,后者代表的是矩阵乘法

*:对应元素相乘

python 复制代码
import numpy as np

a = np.array([
    [1, 2],
    [3, 4]
])

b = np.array([
    [10, 20],
    [30, 40]
])

print(a * b)
"""
实际上,a*b进行的操作是元素进行运算
a*b输出结果为:
[[10 40]
 [90 160]]
"""

@:矩阵乘法

python 复制代码
import numpy as np

a = np.array([
    [1, 2],
    [3, 4]
])

b = np.array([
    [10, 20],
    [30, 40]
])
print(a @ b) # 这里对应的是矩阵乘法
"""
根据线性代数
第1行第1列的数值为1*10+2*30=70,第1行第2列的数值为1*20+2*40=100
第2行第1列的数值为3*10+4*30=150,第2行第2列的数值为3*20+4*40=220
最后a @ b的结果为:
[[ 70 100]
 [150 220]]
"""

矩阵乘法中的重要规则

tex 复制代码
假设:
A.shape = (2, 3)
B.shape = (3, 4)
则:
A @ B是可以被计算的,即前矩阵的列数对应后矩阵的行数,这里输出的是(2,4)的矩阵

Numpy中的统计操作

常用统计函数

python 复制代码
np.sum()  # 求和函数
np.mean() # 平均值函数
np.max()  # 最大值函数
np.min()  # 最小值函数
python 复制代码
import numpy as np

a = np.array([10, 20, 30, 40])

print(np.sum(a))  # 输出100
print(np.mean(a)) # 输出25.0
print(np.max(a))  # 输出40
print(np.min(a))  # 输出10

axis(轴)

二维数组中,np.sum()是所有元素相加,但是np.sum(a, axis=0)np.sum(a, axis=1)的结果不同,axis是Numpy中的"轴"概念,对于二维数组,axis=0是按列计算,axis=1是按行计算,axis 指的是"沿着哪个维度进行压缩/聚合"

python 复制代码
# axis=0 → 压缩行这个方向 → 每列得到一个结果
# axis=1 → 压缩列这个方向 → 每行得到一个结果

a = np.array([
    [1, 2, 3],
    [4, 5, 6]
])
np.sum(a, axis=0) # 这里指的是沿着第0维进行计算,也就是把每一列往下加 结果为[5 7 9]
np.sum(a, axis=1) # 这里可以理解成把每一行的元素加起来 结果为[6 15]

a = np.array([
    [10, 20, 30],
    [40, 50, 60],
    [70, 80, 90]
])
np.sum(a) # 输出450
np.sum(a, axis=0) # 输出[120 150 180]
np.sum(a, axis=1) # 输出[60 150 240]

axis不止适用于求和函数,同样适用于其他统计函数

python 复制代码
a = np.array([
    [10, 20, 30],
    [40, 50, 60]
])
np.mean(a, axis=0) # 根据列计算每列的平均值,结果为[25. 35. 45.]
np.mean(a, axis=1) # 根据行计算每行的平均值,结果为[20. 50.]
python 复制代码
# 综合检验
import numpy as np

data = np.arange(1, 13) # 从1开始到13结束(不包含13)的一维数组

data = data.reshape(3, 4) # 利用reshape1完成数组转换,3行4列

print(data)

print(data.shape) # 输出(3,4)

print(data[:, 1]) # 输出data中所有行第2列,为[2 6 10]

print(data * 2)   # 对data中的元素进行乘2操作

print(np.sum(data, axis=0)) # 按列对data中的元素进行求和,为[15 18 21 24]

print(np.mean(data, axis=1)) # 按行对data中的元素进行平均,为[2.5 6.5 10.5]

dtype

type和 dtype的区别

python 复制代码
import numpy as np

a = np.array([1, 2, 3])

print(type(a)) # 输出 <class 'numpy.ndarray'> 这里输出的是a是什么类型的对象
print(a.dtype) # 输出 int64 这里输出的是a里面的数据是什么类型
python 复制代码
a = np.array([1, 2, 3], dtype=float) # 指定dtype,要求把它保存成浮点数

print(a) # 输出[1. 2. 3.]
print(a.dtype) # 输出float64

Numpy中的随机数

np.random.rand()

python 复制代码
import numpy as np

a = np.random.rand(3) # 随机生成3个0到1之间的随机浮点数

print(a) # 每次运行结果不同

# 可以生成二维数组
a = np.random.rand(2, 3) # 随机生成2行3列的二维数组,数组中的元素为0到1之间的随机浮点数

np.random.randint()

python 复制代码
a = np.random.randint(1, 10, 5) # 随机生成1到10(不包含10)之间的数,生成5个

print(a)

# 生成二维数组
a = np.random.randint(1, 10, (2, 3)) # 随机生成2行3列的二维数组,数组中的元素为1到10(不包含)之间的随机整数
print(a)

布尔索引

布尔索引就是把满足条件的元素筛选出来,做数据集处理、异常值处理、模型参数分析时都会用到

python 复制代码
a = np.array([10, 20, 30, 40, 50])
print(a>30) # 输出[False False False  True  True]
print(a[a>30]) # 输出[40 50]

多条件布尔索引

python 复制代码
a = np.array([10, 20, 30, 40, 50, 60, 70])
result = a[(a > 30) & (a < 60)] # 找出大于30并且小于60的数据
result = a[(a < 20) | (a > 60)] # 找出小于20或者大于60的数据
result = a[~(a > 30)] # 找出小于等于30的数据

Numpy数组的复制、拼接与拆分

数组的复制:copy()

python 复制代码
import numpy as np

a = np.array([1, 2, 3])

b = a

b[0] = 100 # b进行变化后,a也会发生相应变化,这里可以理解为b和a指向了同一个数组

print(a) # 输出[100 2 3],受到了影响
print(b)

真正的复制:copy()

python 复制代码
import numpy as np

a = np.array([1, 2, 3])

b = a.copy() # 这里相当于复制操作,创建了一共真正独立的新数组

b[0] = 100

print(a) # 输出[1 2 3],不受影响
print(b) # 输出[100 2 3]

数组拼接

机器学习处理数据时,经常需要把多个数组合在一起,其中最基础的是:np.concatenate()

python 复制代码
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

c = np.concatenate([a, b])

print(c) # 输出[1 2 3 4 5 6],将2个数组进行了拼接

二维数组的拼接

python 复制代码
a = np.array([
    [1, 2],
    [3, 4]
])

b = np.array([
    [5, 6],
    [7, 8]
])

c = np.concatenate([a, b], axis=0) # 以列为单位进行拼接 这里进行的是上下拼接
c = np.concatenate([a, b], axis=1) # 以行为单位进行拼接 这里进行的是左右拼接

数组拆分

最基础的数组拆分是np.split()

python 复制代码
a = np.array([1, 2, 3, 4, 5, 6])

b, c = np.split(a, 2) # 将原来的单个数组拆分为2个,即6个元素平均拆成2份

print(b) # 输出[1 2 3]
print(c) # 输出[4 5 6]

Numpy与PyTorch

NumPy 的数组叫ndarray,PyTorch 的核心数据结构叫Tensor,可以将两种理解为功能十分相似的两种多维数组

python 复制代码
import numpy as np
import torch

a = np.array([1, 2, 3])
b = torch.tensor([1, 2, 3])

Numpy与PyTorch

python 复制代码
# NumPy → PyTorch
import numpy as np
import torch

a = np.array([1, 2, 3])

b = torch.tensor(a) # 这里是将NumPy中的ndarray数据结构转换为了PyTorch Tensor

print(b)
python 复制代码
# PyTorch → NumPy
import numpy as np
import torch

a = torch.tensor([1, 2, 3])

b = a.numpy() # 这里是将PyTorch中的tensor数据结构转换为了NumPy ndarray

print(b)

torch.tensor() 和 torch.from_numpy()

python 复制代码
import numpy as np
import torch

a = np.array([1, 2, 3])

b = torch.from_numpy(a) # 把 NumPy 数组转换成Tensor

两者均可完成NumPy → Tensor,两者在数据共享、复制行为、dtype 等细节上存在区别

Tensor和ndarray的shape

python 复制代码
a = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

print(a.shape) # 输出(2, 3)

b = torch.tensor([
    [1, 2, 3],
    [4, 5, 6]
])

print(b.shape) # 输出torch.Size([2, 3])

NumPy和PyTorch的相同点

绝大多数Numpy中知识可以迁移到Pytorch中

NumPy PyTorch
ndarray Tensor
a.shape b.shape
a.reshape() b.reshape()
a.sum() b.sum()
a.mean() b.mean()
a @ b a @ b
a.dtype b.dtype
python 复制代码
import numpy as np # 导入Numpy包

data = np.arange(1, 13) # 创建一个一维的连续数组

data = data.reshape(3, 4) # 将数组转换为3行4列的数组[[1 2 3 4][5 6 7 8][9 10 11 12]]

print(data.shape) # 输出data的shape,为(3,4)

selected = data[data > 5] # 选出data中大于5的元素并进行赋值 [6 7 8 9 10 11 12]

print(selected) # [6 7 8 9 10 11 12]

mean = np.mean(data, axis=0) # 按列进行求平均数

print(mean) # 输出平均数

new_data = data * 2 # 对data中所有元素进行乘2操作

print(new_data) # 输出乘2操作后的data

a = np.array([1, 2, 3]) # 创建一维数组
b = a.copy() # 复制操作

b[0] = 100 # 对b进行修改

print(a) # [1 2 3]
print(b) # [100 2 3]
相关推荐
总有刁民想爱朕ha1 小时前
零基础Python开发「图片批量转MP4视频」工具,本地离线、免费无水印
开发语言·python·音视频
捧 花1 小时前
FastAPI 基础语法:从一个完整接口理解 Web API 的设计
前端·python·fastapi·middleware
Ming_studying2 小时前
Python批量压缩图片:支持JPG_PNG_WebP、尺寸限制与CSV报告
开发语言·图像处理·python·pillow·图片压缩
大熊背2 小时前
ISP图像处理中大数乘法溢出处理(一)
人工智能·python·算法·溢出处理
何以解忧,唯有..2 小时前
Python协程详解:从生成器到async/await的完整指南
开发语言·python
hhzz2 小时前
智慧校园13类视频异常检测:数据集与预训练模型全攻略
人工智能·pytorch·python·深度学习·目标检测·机器学习
浩腾数字多媒体2 小时前
如何判断专业电子留言厂家适配条件?
大数据·人工智能·python
会编程的吕洞宾2 小时前
DeepAgents In Action学习(Third)
python·学习·django
'2062 小时前
**写了个自动整理下载视频的脚本:按片名归档、自动重命名、生成目录索引
开发语言·python·ffmpeg·音视频·cctv