python入门系列二十五(numpy 必知必会科学计算库)

280 阅读4分钟

1.引言

numpy单词拆解开来看,有两部分:numerical+python。是python科学计算基础库,提供高性能多维数组对象和数学工具,在很多应用领域作为基础核心的存在。比如:

  • 机器学习以及深度学习框架TensorFlow和PyTorch底层依赖
  • 数据分析库pandas和可视化库matplotlib底层依赖
  • 图像处理和信号分析
  • 工程计算和数值模拟

等等。如果我们用一句话来归纳numpy的优势,那就是高性能低消耗能力丰富的科学计算库。具体拆开看执行速度快,资源消耗少,丰富数学函数。

2.案例

2.1.环境准备

使用numpy库,需要安装一下。

pip install numpy

2.2.初步体验

前面介绍说numpy是高性能的科学计算库,如何高性能,我们先来直观看一个案例:通过比较python列表和numpy实现100万元素平方计算耗时

import time
import numpy as np

# Python列表实现平方
py_list = list(range(1000000))
start = time.time()
py_squares = [x**2 for x in py_list]
print(f"Python耗时: {time.time()-start:.4f}s")

# NumPy实现平方
np_arr = np.arange(1000000)
start = time.time()
np_squares = np_arr ** 2
print(f"NumPy耗时: {time.time()-start:.4f}s")

image.png

通过案例结果,我们看到numpy的高性能名不虚传,比起python列表操作,存在数量级的提升优势!

2.3.核心数据结构

numpy库的核心数据结构:ndarray 。即n维数组。

2.3.1.数组常见常见方式

基础创建方法:

import numpy as np

# 数组基础创建方法
# 从Python列表创建,一维数组
list_arr = np.array([1, 2, 3])
print(f"从Python列表创建,一维数组{list_arr }")

# 从元组创建,一维数组
tuple_arr = np.array((4, 5, 6))
print(f"从元组创建,一维数组{tuple_arr}")

# 二维数组(矩阵)
matrix = np.array([[1, 2], [3, 4]])
print(f"创建二维数组(矩阵){matrix}")

image.png

特殊数组:

import numpy as np

# 特殊数组创建方法
# 创建2行3列全0数组
zeros = np.zeros((2,3))
print(f"2行3列全0数组{zeros}")

# 创建一维全1数组
ones = np.ones((3,))
print(f"一维全1数组{ones}")

# 创建3x3单位矩阵
identity = np.eye(3)
print(f"3x3单位矩阵{identity}")

# 创建2x2随机数组(0-1均匀分布)
random_arr = np.random.rand(2,2)
print(f"2x2随机数组{random_arr}")

image.png

序列:

import numpy as np

# 序列创建方法
# 创建0到10的序列,步长为2
range_arr = np.arange(0, 10, 2)
print(range_arr)

# 创建0到1等差数列,元素个数为5
linspace_arr = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1.]
print(linspace_arr)

image.png

2.3.2.数组属性

除了创建n维数组,在实际应用中,我们还需要关心数组相关的属性。

import numpy as np

# 数组相关属性
# 创建一个2行3列的二维数组
arr = np.array([[1,2,3],[4,5,6]])

print("维度数:", arr.ndim)     
print("形状:", arr.shape)
print("元素总数:", arr.size)
print("数据类型:", arr.dtype)
print("每个元素字节数:", arr.itemsize)

image.png

2.4.数组索引操作

2.4.1.索引切片

切片的概念如同python列表切片,含义上是一样的,我们看具体操作

import numpy as np

# 数组切片操作
#  创建一个3行3列的数组
arr = np.array([[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]])

# 第0行第1列
print(f"第0行第1列:{arr[0, 1]}")

# 所有行第1列
print(f"所有行第1列:{arr[:, 1]}")

# 隔行隔列
print(f"隔行隔列:{arr[::2, ::2]}")

# 布尔索引
mask = arr > 5
print(f"布尔索引:{arr[mask]}")

image.png

2.4.2.形状操作

import numpy as np

# 形状操作
# 改变形状
arr = np.arange(6)
# 调整形状为2行3列
reshaped = arr.reshape(2,3)
print(f"调整形状为2行3列:{reshaped}")

# 转置操作:3行2列
transposed = reshaped.T
print(f"转置操作:{transposed}")

# 拼接数组
a = np.array([1,2])
b = np.array([3,4])
concat = np.concatenate([a,b])
print(f"拼接数组:{concat}")

# 分割数组:分成3个等长数组
split_arr = np.split(np.arange(9), 3)
print(f"分割数组:{split_arr}")

image.png

2.5.数学运算广播机制

2.5.1.基础运算

import numpy as np

# 数学基础运算
a = np.array([1,2,3])
b = np.array([4,5,6])

print("加法:", a + b)
print("乘法:", a * 2)
print("矩阵乘法:", a.dot(b))
print("三角函数:", np.sin(a))
print("指数运算:", np.exp(a))

image.png

2.5.2.广播机制

广播机制有三条法则:

  • 维度扩展,即小维度数组左侧补1
  • 形状扩展,即尺寸为1的维度扩展匹配
  • 禁止广播,即所有维度尺寸必须为1或相等
import numpy as np

# 广播机制
# 标量与数组运算
print(10 * np.ones((2,3)))

# 不同维度运算
A = np.array([[1,2],[3,4]])  # (2,2)
B = np.array([10,20])        # (2,)
print(A + B)  # B广播为[[10,20],[10,20]]

image.png

2.6.统计与聚合函数

2.6.1.常用统计方法

import numpy as np

# 常用统计方法
# 100个正态分布数
data = np.random.normal(0, 1, 100)
print(f"100个正态分布数{data}")

print("均值:", np.mean(data))
print("标准差:", np.std(data))
print("中位数:", np.median(data))
print("最大值索引:", np.argmax(data))
print("累计乘积:", np.cumprod([1,2,3,4]))

image.png

2.6.2.轴方向计算

import numpy as np

# 轴方向计算
arr = np.array([[1,2], [3,4], [5,6]])

print("列求和:", arr.sum(axis=0))
print("行最大值:", arr.max(axis=1))
print("整体均值:", arr.mean())

image.png