Numpy入门教程

Python库Numpy入门

NumPy是Python中科学计算的基本包。它是一个Python库,提供多维数组对象、各种派生对象(如掩码数组和矩阵),以及用于对数组进行快速操作的各种例程,包括数学、逻辑、形状操作、排序、选择、I/O、离散傅立叶变换、基本线性代数、基本统计运算、随机模拟等等。

numpy的核心是ndarray对象,这是一个多维数组。


安装

用pip安装

pip install numpy

官网下载

Release NumPy v1.26


基本使用

多维数组概念

在numpy中, 维度(dimensions) 被称作 轴(axes)

[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]

在上面这个数组中,有两个轴,即是二维数组(二维空间)。第一个轴有三个元素,即分别为[ 0 1 2 3 4 ][ 5 6 7 8 9 ][ 10 11 12 13 14 ],长度为3。第二个轴有五个元素,即长度为5。

创建一个数组

numpy数组的类为ndarray,这有别于python标准库中的array.array。

以下为创建numpy数组的示例:

# 先导入numpy,别称为np
import numpy as np
# 生成一个5x3的二维数组a
a = np.arange(15).reshape(5,3)
print(a)
# 将会输出:
# [[ 0  1  2]
# [ 3  4  5]
# [ 6  7  8]
# [ 9 10 11]
# [12 13 14]]

除此之外,ndarray还有多种属性,如下:

# 数组的维数
print(a.ndim)
# 结果:2
# 表示数组为2维空间

# 数组的形状
print(a.shape)
# 结果:(5,3)
# 表示数组为5x3的二维数组

# 数组的类型(data type)
print(a.dtype)

# 数组中每个元素的大小(bit)
print(a.itemsize)

# 输出数组在内存中的真实数据
# 通常不会用到该属性
print(a.data)

同样,也能通过python标准库中的列表来创建numpy数组:

# 调用np.array()方法即可把列表转换成数组
a = np.array([1,2,3])
# 同样浮点型也适用
a = np.array([1.2,2.4,1.8])

# 还可以转换成多维数组
b = np.array([(1.5, 2, 3), (4, 5, 6)])
print(b)
# 结果:
# [[1.5 2.  3. ]
#  [4.  5.  6. ]]
b = np.array([[1, 2], [1, 2]], dtype=complex)
# complex是复数类型

为了提高效率,numpy还提供了创建空数组的方法:

# 创建全为0的2x3的二维数组
np.zeros((2,3))
# 创建全为1的2x3x4的三维数组
np.ones((2,3,4))
# 创建空数组(数据值取决于内存,即随机)
np.empty((2,3))

我们再回顾本段落第一个示例,里面用的arange方法可以生成一个递增或者递减的序列:

# np.arange(start,stop,step)
#           起始   结束  步进
# 创建一个从[0,5)的一个一维数组
a = np.arange(5)
print(a)
# 结果:[0 1 2 3 4]

# 创建一个从[10,30),步进为5的一维数组
a = np.arange(10,30,5)
# 结果:[10 15 20 25]

# 也可以是递减的
a = np.arange(30,10,-5)
# 结果:[30 25 20 15]

如果想生成带小数的序列,推荐使用linspace方法,它可以生成一个等间隔的序列:

# np.linspace(start,stop,num)
#             起始   结束  数的个数
# 把[0,5]等间距的分成6个数
d = np.linspace(0, 5, 6)
print(d)
# 结果:[0. 1. 2. 3. 4. 5.]
# 注意:间距=(stop-start)/(num-1)

# 计算sin(x)在[0,2π]区间内等间距的10个点的数值
from numpy import pi
x = np.linspace(0, 2 * np.pi, 10)
f = np.sin(x)
print(f)
# 结果:[ 0.00000000e+00  6.42787610e-01  9.84807753e-01  8.66025404e-01
#        3.42020143e-01 -3.42020143e-01 -8.66025404e-01 -9.84807753e-01
#       -6.42787610e-01 -2.44929360e-16]

这些序列还可以用reshape()方法重新分配为新的多维数组:

# 创建一个1~10的5x2的二维数组
a = np.arange(1,11).reshape(5,2)

数组操作(基本运算)

先生成两个ndarray的变量:

a = np.array([10, 10, 10])
# [10,10,10]
b = np.arange(3)
# [0 ,1 ,2]

进行如下运算:

# a数组减去b数组
a - b
# 得到:[10,9,8]

# b数组的2次幂
b**2
# 得到:[0,1,4]

# b数组是否小于1
b < 1
# 得到:[True, False, False]

以下是多维数组的运算:

A = np.array([[1,1],
              [0,1]])
B = np.array([[2,0],
              [3,4]])

# 矩阵对应元素相乘
A * B
# 得到:
# [[2 0]
#  [0 4]]

# 以下运算才是矩阵的相乘(线性代数)
A @ B
# 得到:
# [[5 4]
#  [3 4]]
A.dot(B)
# 以上也能实现矩阵相乘 等同于 A@B

# 一个数乘以矩阵
3 * B
# 得到:
# [[ 6  0]
#  [ 9 12]]

A *= 3
# 相当于 A = A * 3
B += A
# 相当于 B = B + A

其他常见的运算:

# 复数运算
np.exp(B * 2j)
# j代表复数

# 求和(数组内所有元素的和)
np.sum(B)

# 求最小元素
np.min(B)

# 求最大元素
np.max(B)

索引和切片

一维数组

对于一维数组而言,和Python自带的列表操作十分的相似:

# 产生10个元素的数组
a = np.arange(10)
# [0 1 2 3 4 5 6 7 8 9]
# 索引为3的元素表示为
a[3]     # 3
# 注意索引从0~9共十个数
# 还可以进行切片 输出索引2,3的数
a[2:4]   # [2 3]
# 也可以设置步长
# 如下可以实现逆序该数组
a[::-1]  # [9 8 7 6 5 4 3 2 1 0]

# 遍历每一个元素
for t in a:
    print(t)
多维数组

在多维数组中,对于每一个轴都有一个索引。

以下是二维数组操作的示例:

# [[ 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]]
a = np.arange(30).reshape(5,6)
# 取第3行第4个元素
# 索引依次为2,3
a[2,3]    # 15
# 当然也能进行切片
# 第一个索引表明只保留第2,3行
# 第二个索引表明取全部元素
a[1:3,:]  # [[12 13 14 15 16 17]
          #  [18 19 20 21 22 23]]

对于N维数组,跟二维数组类似,a[1,2,3, ...],有N个索引可以使用。

形状操作

最常用的方法还是reshape()方法,示例如下:

# 3行4列的矩阵
a = np.arange(12).reshape(3, 4)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
# 改变成6行2列的矩阵
a = a.reshape(6, 2)
# [[ 0  1]
#  [ 2  3]
#  [ 4  5]
#  [ 6  7]
#  [ 8  9]
#  [10 11]]
# 改变成2x3x2的三维数组
a = a.reshape(2, 3, 2)
# [[[ 0  1]
#   [ 2  3]
#   [ 4  5]]

#  [[ 6  7]
#   [ 8  9]
#   [10 11]]]

还可以用ravel()方法将多维数组展开为1维数组,即列表:

# 2x3x2的三维数组
a = np.arange(12).reshape(2, 3, 2)
# 展开为一维数组
a = a.ravel()
# [ 0  1  2  3  4  5  6  7  8  9 10 11]

ndarray中还有一个T的属性,可以获得该矩阵的转置:

# 3行4列的矩阵
a = np.arange(12).reshape(3, 4)
# 输出a的转置
print(a.T)
# [[ 0  4  8]
#  [ 1  5  9]
#  [ 2  6 10]
#  [ 3  7 11]]
# 变成4行3列的了,元素也转置了

相比于reshape()只能返回一个修改后的数组,resize()方法可以直接修改当前的数组,不用接受返回值,如下示例:

# 3行4列的矩阵
a = np.arange(12).reshape(3, 4)
# 以下两句代码的作用是相同的
a = a.reshape(4, 3)
a.resize(4, 3)
# 打印a
print(a)

拼接和分离数组

拼接
垂直拼接

np.vstack()

水平拼接

np.hstack()

分离
垂直分离

np.vsplit()

水平分离

np.hsplit()

数组拷贝

类似Python中的对象,以下代码并不能直接复制数组:

a = np.arange(12).reshape(3, 4)
b = a
# a和b实际是相同的
print(a is bs)
# True
浅拷贝

浅拷贝并不复制里面的元素,也就是说两个变量共享里面的元素,如下示例:

a = np.arange(12).reshape(3, 4)
# b是a的浅拷贝
b = a.view()
# b中的元素不是自己的
print(b.flags.owndata)
# False
# b改变形状并不会影响a
b.resize((4,3))
print(b)
# [[ 0  1  2]
#  [ 3  4  5]
#  [ 6  7  8]
#  [ 9 10 11]]
print(a)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
# 但是改变b中的元素会影响a的元素
b[0, 0] = 100
print(a)
# [[100   1   2   3]
#  [  4   5   6   7]
#  [  8   9  10  11]]
深拷贝

使用copy()方法可以完全拷贝里面的所有元素,让他们成为两个完全独立的变量:

a = np.arange(12).reshape(3, 4)
b = a.copy()
# 此时无论b中元素怎么改变都不会影响a的任何元素

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值