名人说:路漫漫其修远兮,吾将上下而求索。------ 屈原《离骚》
创作者:Code_流苏(CSDN) (一个喜欢古诗词和编程的Coder😊)目录
- [一、NumPy 简介](#一、NumPy 简介)
- [1. 什么是 NumPy?为什么使用 NumPy?](#1. 什么是 NumPy?为什么使用 NumPy?)
- [2. 安装与导入](#2. 安装与导入)
- 二、多维数组操作
- [1. 创建数组](#1. 创建数组)
- [2. 数组属性](#2. 数组属性)
- [3. 数组索引与切片](#3. 数组索引与切片)
- 三、广播机制
- [1. 广播的概念与应用](#1. 广播的概念与应用)
- [2. 向量化计算的优势](#2. 向量化计算的优势)
- 四、练习:实现矩阵加法和乘法
- [1. 矩阵加法](#1. 矩阵加法)
- [2. 矩阵乘法](#2. 矩阵乘法)
- 五、总结与进阶方向
- 参考资源
专栏介绍: Python星球日记专栏介绍(持续更新ing)
更多Python知识,请关注我、订阅专栏《 Python星球日记》,内容持续更新中...
🌟引言 : 欢迎来到Python星球🪐的第22天!
今天我们正式进入数据分析与可视化进阶篇,从NumPy基础开始我们的新旅程。NumPy是Python数据分析的基石,掌握它将为你打开数据科学的大门。
一、NumPy 简介
1. 什么是 NumPy?为什么使用 NumPy?
NumPy (Numerical Python)是Python中用于科学计算的基础库,它提供了高性能的多维数组对象和处理这些数组的工具。NumPy是数据分析、机器学习 等领域的基础,几乎所有数据科学相关的Python库都以NumPy为基础。
使用NumPy的主要优势:
优势 | 描述 |
---|---|
1️⃣高效的内存管理 | NumPy数组在内存中是连续存储的,比Python原生列表更加高效 |
2️⃣执行速度快 | NumPy底层使用C语言实现,处理大规模数据时比Python原生列表快10-100 倍 |
3️⃣丰富的数学函数 | 内置了大量的数学函数和线性代数操作 |
4️⃣广播功能 | 能够高效地进行不同形状数组之间的运算 |
5️⃣与其他库的兼容性 | 几乎所有数据科学相关的Python库都支持NumPy数组 |

2. 安装与导入
在开始使用NumPy
之前,我们需要先安装它。可以使用pip
进行安装:
python
pip install numpy

安装完成后,在Python脚本中导入NumPy:
python
import numpy as np # 通常使用np作为NumPy的简写别名

💡 小贴士 :使用别名
np
是数据科学社区的通用约定,这样可以减少代码量并提高可读性。
二、多维数组操作
NumPy的核心是ndarray(N-dimensional array,多维数组)对象,它是一个快速、灵活的大数据集容器。

1. 创建数组
有多种方法可以创建NumPy数组:
1️⃣从Python列表创建一维数组
使用np.array()
函数从Python列表创建一个一维NumPy数组,这是NumPy中最基本的数组创建方法。
python
import numpy as np
# 从Python列表创建数组
arr1 = np.array([1, 2, 3, 4, 5])
print("一维数组:", arr1)

2️⃣创建二维数组
创建二维数组(矩阵),通过传入嵌套列表来定义行和列。二维数组是科学计算中常用的数据结构。
python
import numpy as np
# 创建二维数组
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print("二维数组:\n", arr2)

3️⃣创建全0数组
这个代码块说明了如何使用np.zeros()
函数创建所有元素都为0的数组。这在初始化数组或作为占位符时非常有用。
python
import numpy as np
# 创建全0数组
zeros = np.zeros((3, 4)) # 3行4列的全0数组
print("全0数组:\n", zeros)

4️⃣创建全1数组
这个代码块展示了np.ones()
函数的使用,它创建一个所有元素都为1的数组。这在需要默认值为1的计算中很有用。
python
import numpy as np
# 创建全1数组
ones = np.ones((2, 3)) # 2行3列的全1数组
print("全1数组:\n", ones)

5️⃣创建等差数列
这个代码块演示了如何使用np.arange()
创建等差数列。该函数类似于Python的range()
,但返回的是NumPy数组而不是列表。
python
import numpy as np
# 创建等差数列
arange = np.arange(0, 10, 2) # 从0开始,步长为2,小于10
print("等差数列:", arange)

6️⃣创建等间隔数值点
这个代码块展示了np.linspace()
函数,它创建指定范围内均匀分布的点。这在绘图和数值积分等应用中特别有用。
python
import numpy as np
# 创建等间隔的数值点
linspace = np.linspace(0, 1, 5) # 从0到1之间均匀分布的5个点
print("等间隔数值点:", linspace)

7️⃣创建随机数组
使用NumPy的随机模块创建随机值数组。随机数在模拟、统计和机器学习中广泛应用。
python
import numpy as np
# 创建随机数组
random_array = np.random.random((2, 2)) # 2×2的随机数组(值在0到1之间)
print("随机数组:\n", random_array)

8️⃣创建单位矩阵
这个代码块展示了如何使用np.eye()
函数创建单位矩阵 。单位矩阵在线性代数运算中具有特殊地位,主对角线为1,其余为0。
python
import numpy as np
# 创建单位矩阵
identity = np.eye(3) # 3×3的单位矩阵
print("单位矩阵:\n", identity)

2. 数组属性
NumPy数组有一些重要的属性,可以帮助我们了解数组的特性:
创建一个 3x4 的 二维数组:

python
import numpy as np
# 创建一个3x4的二维数组
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# shape:返回数组的形状(每个维度的大小)
print("数组形状:", arr.shape) # 输出:(3, 4)
# ndim:返回数组的维度数量
print("维度数量:", arr.ndim) # 输出:2
# size:返回数组元素的总数
print("元素总数:", arr.size) # 输出:12
# dtype:返回数组元素的数据类型
print("数据类型:", arr.dtype) # 输出:int64(可能因系统而异)
# itemsize:返回数组中每个元素的字节大小
print("元素字节大小:", arr.itemsize) # 输出:8(对于64位整数)
# 创建指定数据类型的数组
float_arr = np.array([1, 2, 3, 4], dtype=np.float32)
print("浮点数组:", float_arr)
print("浮点数组数据类型:", float_arr.dtype) # 输出:float32
输出结果:
python
数组形状: (3, 4)
维度数量: 2
元素总数: 12
数据类型: int32
元素字节大小: 4
浮点数组: [1. 2. 3. 4.]
浮点数组数据类型: float32
注意:了解数组的数据类型对于内存优化和性能非常重要,尤其是处理大型数据集时。
3. 数组索引与切片
NumPy数组支持 与Python列表类似的索引和切片操作,但功能更加强大:
python
import numpy as np
# 创建一个3x4的二维数组
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# 访问单个元素:arr[行, 列]
print("第2行第3列的元素:", arr[1, 2]) # 输出:7
# 访问整行
print("第1行:", arr[0]) # 输出:[1 2 3 4]
# 访问整列(需要使用:表示"所有行")
print("第2列:", arr[:, 1]) # 输出:[ 2 6 10]
# 切片:arr[行起始:行结束, 列起始:列结束]
print("子数组(前2行,中间2列):\n", arr[0:2, 1:3])
# 输出:
# [[2 3]
# [6 7]]
# 使用负索引(从末尾开始计数)
print("最后一行:", arr[-1]) # 输出:[ 9 10 11 12]
print("倒数第二列:", arr[:, -2]) # 输出:[ 3 7 11]
# 条件索引(布尔索引)
print("大于6的元素:", arr[arr > 6])
# 输出:[ 7 8 9 10 11 12]
# 花式索引(使用索引数组)
print("第1行和第3行:\n", arr[[0, 2]])
# 输出:
# [[ 1 2 3 4]
# [ 9 10 11 12]]
输出结果:
python
第2行第3列的元素: 7
第1行: [1 2 3 4]
第2列: [ 2 6 10]
子数组(前2行,中间2列):
[[2 3]
[6 7]]
最后一行: [ 9 10 11 12]
倒数第二列: [ 3 7 11]
大于6的元素: [ 7 8 9 10 11 12]
第1行和第3行:
[[ 1 2 3 4]
[ 9 10 11 12]]
三、广播机制
1. 广播的概念与应用
广播 (Broadcasting)是NumPy 的一个强大特性 ,它允许不同形状的数组在算术运算时自动扩展,使数组间的运算更加灵活高效。
遵循以下规则:
- 如果两个数组的维度数不同,形状较小的数组会在左侧补1
- 如果两个数组在某个维度上的大小不匹配,但其中一个的大小为1,则该维度会被"广播"以匹配另一个数组

让我们看一些广播的例子:
1️⃣不同形状数组之间的运算
python
import numpy as np
# 创建数组
a = np.array([1, 2, 3]) # 一维数组:(3,)
b = 5 # 标量
# 数组与标量运算 - 广播机制自动将标量扩展为数组
print("数组+标量:", a + b) # 输出:[6 7 8]
print("数组*标量:", a * b) # 输出:[5 10 15]
# 不同形状数组之间的运算
a = np.array([[1, 2, 3],
[4, 5, 6]]) # 形状为(2, 3)
b = np.array([10, 20, 30]) # 形状为(3,)
# b会被广播成形状(2, 3)的数组,然后进行元素级加法
print("不同形状数组相加:\n", a + b)
# 输出:
# [[11 22 33]
# [14 25 36]]

2️⃣更复杂的广播示例
python
import numpy as np
# 创建数组
a = np.array([1, 2, 3]) # 一维数组:(3,)
b = 5 # 标量
# 数组与标量运算 - 广播机制自动将标量扩展为数组
print("数组+标量:", a + b) # 输出:[6 7 8]
print("数组*标量:", a * b) # 输出:[5 10 15]
# 更复杂的广播示例
a = np.array([[1, 2, 3],
[4, 5, 6]]) # 形状为(2, 3)
b = np.array([[10], [20]]) # 形状为(2, 1)
# b会被广播成形状(2, 3)的数组,每行重复列的值
print("列向量广播:\n", a + b)
# 输出:
# [[11 12 13]
# [24 25 26]]

2. 向量化计算的优势
向量化 是指使用向量 (数组)操作替代循环 的编程风格,它是NumPy高性能的关键。
向量化的主要优势:
- 代码简洁:向量化操作大大减少了代码量
- 执行速度快:NumPy的向量化操作底层是用C实现的,远比Python循环快
- 内存效率高:向量化操作通常更加内存高效
下面是循环和向量化的性能对比:
python
import numpy as np
import time
# 创建两个大数组
size = 10000000
a = np.random.random(size)
b = np.random.random(size)
# 使用Python循环计算
start_time = time.time()
result_loop = np.zeros(size)
for i in range(size):
result_loop[i] = a[i] + b[i]
loop_time = time.time() - start_time
print(f"循环耗时: {loop_time:.6f}秒")
# 使用NumPy向量化计算
start_time = time.time()
result_vectorized = a + b
vectorized_time = time.time() - start_time
print(f"向量化耗时: {vectorized_time:.6f}秒")
# 计算加速比
print(f"向量化操作比循环快 {loop_time/vectorized_time:.1f} 倍")
# 验证两种方法的结果是否相同
print("结果是否相同:", np.allclose(result_loop, result_vectorized))
输出结果:
python
循环耗时: 1.961162秒
向量化耗时: 0.028977秒
向量化操作比循环快 67.7 倍
结果是否相同: True
最佳实践 :尽可能使用
NumPy
的向量化操作 ,避免 使用Python循环处理NumPy数组。
四、练习:实现矩阵加法和乘法
下面我们将使用NumPy实现矩阵的加法和乘法操作。
1. 矩阵加法
矩阵加法是元素级操作,要求两个矩阵形状相同。

python
import numpy as np
# 创建两个2x3矩阵
A = np.array([[1, 2, 3],
[4, 5, 6]])
B = np.array([[7, 8, 9],
[10, 11, 12]])
# 矩阵加法
C = A + B
print("矩阵加法结果:\n", C)
# 另一种实现方式
D = np.add(A, B)
print("使用np.add()的结果:\n", D)
# 验证两种方法结果相同
print("两种方法结果是否相同:", np.array_equal(C, D))
输出结果:
python
矩阵加法结果:
[[ 8 10 12]
[14 16 18]]
使用np.add()的结果:
[[ 8 10 12]
[14 16 18]]
两种方法结果是否相同: True
2. 矩阵乘法
NumPy提供了多种实现矩阵乘法的方式:

python
import numpy as np
# 创建矩阵
A = np.array([[1, 2],
[3, 4],
[5, 6]]) # 3x2矩阵
B = np.array([[7, 8, 9],
[10, 11, 12]]) # 2x3矩阵
# 矩阵乘法(点积)
C = np.dot(A, B)
print("矩阵乘法结果 (np.dot):\n", C)
# 使用@运算符(Python 3.5+)
D = A @ B
print("矩阵乘法结果 (@运算符):\n", D)
# 使用matmul函数
E = np.matmul(A, B)
print("矩阵乘法结果 (np.matmul):\n", E)
# 元素级乘法(不是矩阵乘法!)
# 需要形状相同的矩阵
F = np.array([[1, 2], [3, 4]])
G = np.array([[5, 6], [7, 8]])
H = F * G # 或 np.multiply(F, G)
print("元素级乘法结果:\n", H)
输出结果:
python
矩阵加法结果:
[[ 8 10 12]
[14 16 18]]
使用np.add()的结果:
[[ 8 10 12]
[14 16 18]]
两种方法结果是否相同: True
注意 :不要混淆矩阵乘法(
np.dot
、@
、np.matmul
)和元素级乘法(*
、np.multiply
)!它们的计算方式和结果完全不同。
五、总结与进阶方向
今天我们学习了NumPy
的基础知识,包括数组创建、属性、索引、切片、广播机制和向量化计算 。NumPy是Python数据分析的基石,掌握好这些基础对后续学习Pandas、Matplotlib等高级库至关重要。
下一步学习方向:
python
- NumPy的高级函数(统计函数、线性代数函数等)
- 结构化数组和记录数组
- 文件I/O操作
- 与Pandas的结合使用
练习建议:
python
1. 尝试使用NumPy解决一些实际问题,如图像处理、数据分析等
2. 探索NumPy的其他创建数组的方法和函数
3. 实践不同形状数组之间的广播操作
4. 比较循环和向量化操作的性能差异
编程提示 :多使用
np.info()
和help()
函数查看NumPy函数的详细说明,例如np.info(np.dot)
会显示dot函数的详细文档。
参考资源
- NumPy官方文档:https://numpy.org/doc/stable/
- NumPy用户指南:https://numpy.org/doc/stable/user/
- NumPy备忘单:https://numpy.org/doc/stable/user/numpy-for-matlab-users.html
希望今天的学习让你对NumPy有了初步的了解。在接下来的日子里,我们将继续深入数据分析与可视化的世界! 有什么关于NumPy的问题,欢迎在评论区留言交流!
下一篇预告 :在第23天的星球之旅中,我们将探索 Pandas 基础
创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)
如果你对今天的内容有任何问题,或者想分享你的学习心得,欢迎在评论区留言讨论!