NumPy 详解:从入门到掌握 – wiki基地


NumPy 详解:从入门到掌握

NumPy(Numerical Python)是 Python 语言的一个开源库,是 Python 科学计算和数据分析领域的核心工具之一。它提供了多维数组对象(ndarray),以及一系列用于快速操作数组的函数。NumPy 的出现极大地提高了 Python 在数值计算方面的性能,是 Pandas、SciPy、Matplotlib、scikit-learn 等众多库的基石。

本文将带你从零开始,逐步深入了解 NumPy 的强大功能和使用方法。

第一部分:初识 NumPy – 为什么需要它?

Python 原生的列表(list)非常灵活,可以存储不同类型的数据,且大小可变。然而,在进行大量的数值计算时,Python 列表的效率较低。主要原因包括:

  1. 异构性: 列表可以存储任何类型的对象,这使得 Python 需要为每个元素存储类型信息和指针,增加了开销。
  2. 性能: 列表的操作通常是在 Python 解释器层面进行,涉及大量的循环,速度慢。
  3. 功能限制: Python 列表没有内置的向量化(vectorization)操作,例如两个列表相加需要手动循环。

NumPy 的 ndarray 对象解决了这些问题:

  1. 同构性: ndarray 只能存储相同数据类型的元素,这使得 NumPy 可以紧凑地存储数据,无需存储额外的类型信息,并且可以通过 C 语言的库来实现高效的数据操作。
  2. 高性能: NumPy 的核心是用 C 和 Fortran 编写的,其操作在底层进行,避免了 Python 循环的开销,实现了向量化计算。这意味着许多操作可以直接应用于整个数组,而无需编写显式的循环。
  3. 丰富的功能: NumPy 提供了大量的数学、统计、线性代数、傅里叶变换等函数,可以直接在 ndarray 上执行。

因此,对于任何涉及大量数值数据的处理和计算任务,使用 NumPy 几乎是不可或缺的选择。

第二部分:安装与导入

安装 NumPy 非常简单,推荐使用 pip 包管理器:

bash
pip install numpy

安装完成后,在 Python 代码中导入 NumPy 通常使用以下惯例:

python
import numpy as np

我们将使用 np 作为 NumPy 的别名贯穿本文。

第三部分:NumPy 的核心 – ndarray 对象

ndarray(n-dimensional array)是 NumPy 中最重要的数据结构。它是一个多维的、同构的、固定大小的项目集合。数组中的每个元素都是相同的数据类型(dtype),并且可以使用一个整数元组来索引。

3.1 创建 ndarray

有多种方法可以创建 ndarray

1. 从 Python 列表或元组创建:

“`python

从列表创建一维数组

list1 = [1, 2, 3, 4, 5]
arr1 = np.array(list1)
print(arr1)
print(type(arr1))
print(arr1.dtype) # 查看数据类型

从列表的列表创建二维数组

list2 = [[1, 2, 3], [4, 5, 6]]
arr2 = np.array(list2)
print(arr2)
print(arr2.shape) # 查看形状(行数, 列数)
print(arr2.ndim) # 查看维度

指定数据类型

arr3 = np.array([1.0, 2.0, 3.0], dtype=np.float64)
print(arr3)
print(arr3.dtype)
“`

2. 使用内置函数创建特定数组:

  • np.zeros(shape): 创建全零数组。
  • np.ones(shape): 创建全一数组。
  • np.empty(shape): 创建一个内容随机(取决于内存状态)的数组,比 zerosones 稍快。
  • np.arange(start, stop, step): 类似于 Python 的 range,创建等差数组。
  • np.linspace(start, stop, num): 创建指定数量的等间隔数组。

“`python

全零数组

zeros_arr = np.zeros((2, 3))
print(zeros_arr)

全一数组

ones_arr = np.ones((4, 2), dtype=np.int32) # 可以指定数据类型
print(ones_arr)

空数组

empty_arr = np.empty((3, 3))
print(empty_arr) # 内容随机

等差数组

range_arr = np.arange(0, 10, 2) # 从0到10(不包含10),步长为2
print(range_arr)

等间隔数组

linspace_arr = np.linspace(0, 1, 5) # 从0到1,共5个点
print(linspace_arr)

创建单位矩阵 (正方形数组)

identity_matrix = np.eye(3)
print(identity_matrix)
“`

3.2 ndarray 的重要属性

ndarray 对象有几个重要的属性可以帮助我们了解数组的信息:

  • shape: 一个元组,表示数组在每个维度上的大小。
  • ndim: 数组的维度(轴的数量)。
  • size: 数组中元素的总数。
  • dtype: 数组中元素的数据类型。
  • itemsize: 数组中每个元素的字节大小。
  • data: 包含实际数组元素的缓冲区对象。

“`python
arr = np.array([[1, 2, 3], [4, 5, 6]])

print(“Shape:”, arr.shape) # (2, 3)
print(“Dimensions:”, arr.ndim) # 2
print(“Size:”, arr.size) # 6
print(“Data type:”, arr.dtype) # int64 (取决于系统和创建方式)
print(“Item size:”, arr.itemsize) # 8 (bytes per element for int64)
“`

理解这些属性对于操作数组至关重要。

第四部分:数组的索引和切片

访问和修改 ndarray 的元素是基本操作。NumPy 提供了比 Python 列表更灵活和强大的索引和切片功能。

4.1 基本索引

类似于 Python 列表,可以使用方括号 [] 加上索引来访问元素。对于多维数组,使用逗号 , 分隔不同维度的索引。

“`python
arr1 = np.array([10, 20, 30, 40, 50])
print(arr1[0]) # 访问第一个元素: 10
print(arr1[-1]) # 访问最后一个元素: 50

arr2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr2[0, 0]) # 访问第一行第一列元素: 1
print(arr2[1, 2]) # 访问第二行第三列元素: 6
print(arr2[2, 1]) # 访问第三行第二列元素: 8
“`

4.2 切片

切片用于获取数组的子数组。使用 start:stop:step 语法,同样使用逗号分隔不同维度的切片。

“`python
arr1 = np.array([10, 20, 30, 40, 50, 60])
print(arr1[1:4]) # 从索引1到3 (不包含4): [20 30 40]
print(arr1[:3]) # 从开始到索引2 (不包含3): [10 20 30]
print(arr1[3:]) # 从索引3到结束: [40 50 60]
print(arr1[::2]) # 所有元素,步长为2: [10 30 50]
print(arr1[::-1]) # 反转数组: [60 50 40 30 20 10]

arr2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr2[0:2, 1:3]) # 访问前两行(0和1),以及这两行的第2列到第3列(索引1和2)

输出:

[[2 3]

[5 6]]

print(arr2[:, 1]) # 访问所有行的第2列(索引1)

输出: [2 5 8] (这是一维数组)

print(arr2[1, :]) # 访问第二行(索引1)的所有列

输出: [4 5 6] (这是一维数组)

“`

重要提示:切片是视图(View),不是副本(Copy)

NumPy 的切片操作通常返回原始数组的视图。这意味着对切片数组的修改会直接反映到原始数组上。这在处理大型数据集时非常高效,因为它避免了复制整个数组。

“`python
arr = np.array([1, 2, 3, 4, 5])
slice_arr = arr[1:4]
print(“Original slice:”, slice_arr) # [2 3 4]

slice_arr[0] = 99 # 修改切片的第一个元素
print(“Modified slice:”, slice_arr) # [99 3 4]
print(“Original array after modification:”, arr) # [ 1 99 3 4 5] – 原始数组也被修改了!

如果你需要一个独立的副本,请使用 .copy() 方法

arr_copy = arr[1:4].copy()
arr_copy[0] = 100
print(“Copy:”, arr_copy) # [100 3 4]
print(“Original array after modifying copy:”, arr) # [ 1 99 3 4 5] – 原始数组未被修改
“`

4.3 布尔索引(花式索引)

布尔索引允许你根据条件选择数组元素。你可以使用一个与原数组形状相同(或可广播)的布尔数组作为索引。

“`python
arr = np.array([10, 20, 30, 40, 50])

创建一个布尔数组,判断元素是否大于25

bool_indices = arr > 25
print(bool_indices) # [False False True True True]

使用布尔数组进行索引

print(arr[bool_indices]) # [30 40 50]

也可以直接将条件表达式放在方括号中

print(arr[arr % 2 == 0]) # 选择偶数元素: [10 20 30 40 50]

在二维数组中使用布尔索引

arr2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr2[arr2 > 5]) # [6 7 8 9] – 结果是一维数组
“`

4.4 整数数组索引(花式索引)

你可以使用整数数组作为索引来选择元素的任意组合。结果数组的形状将根据索引数组的形状确定。

“`python
arr = np.array([10, 20, 30, 40, 50])

选择索引 0, 2, 4 的元素

print(arr[[0, 2, 4]]) # [10 30 50]

选择索引 4, 2, 0 的元素 (可以改变顺序)

print(arr[[4, 2, 0]]) # [50 30 10]

重复选择索引

print(arr[[0, 0, 2, 2]]) # [10 10 30 30]

arr2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

选择 (0,0), (1,1), (2,2) 的元素 (对角线)

print(arr2[[0, 1, 2], [0, 1, 2]]) # [1 5 9] – 结果是一维数组

选择行索引 [0, 2],列索引 [1, 0]

会组合成 (0,1), (0,0), (2,1), (2,0) 这四个点

print(arr2[[0, 0, 2, 2], [1, 0, 1, 0]]) # [2 1 8 7] – 结果是一维数组

如果想选择特定的行或列子集,并保持二维结构

选择行索引 [0, 2]

print(arr2[[0, 2], :])

输出:

[[1 2 3]

[7 8 9]]

选择列索引 [1, 0]

print(arr2[:, [1, 0]])

输出:

[[2 1]

[5 4]

[8 7]]

“`

重要提示:整数数组索引和布尔索引通常返回副本(Copy),不是视图(View)

与切片不同,使用整数数组索引或布尔索引获取的数组通常是原始数组的副本。修改这些副本不会影响原始数组。

第五部分:数组操作

NumPy 提供了丰富的函数来操作和处理数组。

5.1 形状操作

改变数组的形状而不改变其数据。

  • reshape(new_shape): 返回一个新形状的数组(如果可能)。
  • ravel() / flatten(): 将多维数组展平为一维数组。flatten() 总是返回副本,ravel() 返回视图(如果可能)。
  • transpose() / .T: 转置数组(交换行列)。
  • resize(new_shape): 直接修改原数组的形状。

“`python
arr = np.arange(12) # [0 1 2 … 11]

将一维数组重塑为 3×4 的二维数组

reshaped_arr = arr.reshape((3, 4))
print(reshaped_arr)

将二维数组展平

flattened_arr = reshaped_arr.ravel()
print(flattened_arr) # 通常返回视图,修改会影响原数组
flattened_copy = reshaped_arr.flatten()
print(flattened_copy) # 总是返回副本

转置数组

transposed_arr = reshaped_arr.T
print(transposed_arr)

修改原数组形状 (不常用,可能丢失数据或填充0)

arr.resize((4, 3))

print(arr)

“`

5.2 组合与分割

将多个数组组合成一个,或将一个数组分割成多个。

  • np.concatenate((arr1, arr2, ...), axis=...): 沿指定轴连接数组。
  • np.vstack((arr1, arr2, ...)): 垂直(按行)堆叠数组。等同于 concatenate(..., axis=0)
  • np.hstack((arr1, arr2, ...)): 水平(按列)堆叠数组。等同于 concatenate(..., axis=1)
  • np.split(arr, indices_or_sections, axis=...): 沿指定轴分割数组。
  • np.vsplit(arr, indices_or_sections): 垂直(按行)分割数组。等同于 split(..., axis=0)
  • np.hsplit(arr, indices_or_sections): 水平(按列)分割数组。等同于 split(..., axis=1)

“`python
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6]])

垂直堆叠

vstacked = np.vstack((arr1, arr2))
print(“VStack:\n”, vstacked)

水平堆叠 (arr2 需要转置或重塑以匹配列数)

arr3 = np.array([[5], [6]])
hstacked = np.hstack((arr1, arr3))
print(“HStack:\n”, hstacked)

concatenate 示例

arr4 = np.array([[7, 8]])

沿着 axis=0 (行) 连接

concatenated_rows = np.concatenate((arr1, arr4), axis=0)
print(“Concatenate (axis=0):\n”, concatenated_rows)

沿着 axis=1 (列) 连接 (需要形状匹配)

arr5 = np.array([[10], [20]])
concatenated_cols = np.concatenate((arr1, arr5), axis=1)
print(“Concatenate (axis=1):\n”, concatenated_cols)

arr_to_split = np.arange(16).reshape((4, 4))
print(“Original array for splitting:\n”, arr_to_split)

垂直分割成2块

vsplit_arrs = np.vsplit(arr_to_split, 2)
print(“VSplit into 2:\n”, vsplit_arrs) # 返回列表,包含两个子数组

水平分割成两块

hsplit_arrs = np.hsplit(arr_to_split, 2)
print(“HSplit into 2:\n”, hsplit_arrs) # 返回列表,包含两个子数组

沿着 axis=1 在索引 1 和 3 处分割

split_at_indices = np.split(arr_to_split, [1, 3], axis=1)
print(“Split at indices [1, 3] along axis=1:\n”, split_at_indices)
“`

第六部分:数学运算与通用函数(ufuncs)

NumPy 最强大的功能之一是其高效的数值计算能力。

6.1 元素级运算

NumPy 数组之间的基本算术运算(+,-,,/,*)都是元素级的。如果两个数组形状相同,则对应位置的元素进行运算。

“`python
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])

print(“Addition:\n”, arr1 + arr2) # 或 np.add(arr1, arr2)
print(“Subtraction:\n”, arr1 – arr2) # 或 np.subtract(arr1, arr2)
print(“Multiplication:\n”, arr1 * arr2) # 或 np.multiply(arr1, arr2)
print(“Division:\n”, arr1 / arr2) # 或 np.divide(arr1, arr2)
print(“Power:\n”, arr1 ** 2) # 或 np.power(arr1, 2)
print(“Square Root:\n”, np.sqrt(arr1))
“`

与标量的运算也是元素级的:

python
arr = np.array([1, 2, 3, 4])
print(arr + 5) # [ 6 7 8 9]
print(arr * 2) # [ 2 4 6 8]

6.2 通用函数 (ufuncs)

通用函数(Universal Functions, ufuncs)是 NumPy 中对 ndarray 执行元素级操作的函数。它们通常快速且支持广播。NumPy 提供了大量的 ufuncs,包括:

  • 数学函数: np.sin, np.cos, np.tan, np.arcsin, np.arctan, np.log, np.exp, np.sqrt, np.abs, np.floor, np.ceil, np.round 等。
  • 比较函数: np.greater (>),np.less(<), np.equal (==),np.not_equal(!=), np.maximum, np.minimum 等。
  • 逻辑函数: np.logical_and, np.logical_or, np.logical_not 等。

“`python
arr = np.array([0, np.pi/2, np.pi])
print(np.sin(arr)) # [0. 1. 0.]

arr_a = np.array([1, 5, 2])
arr_b = np.array([4, 3, 6])
print(np.maximum(arr_a, arr_b)) # [4 5 6]

arr_bool = np.array([True, False, True])
print(np.logical_not(arr_bool)) # [False True False]
“`

6.3 聚合函数

NumPy 提供了用于计算数组总和、平均值、最小值、最大值等的聚合函数。这些函数可以应用于整个数组,也可以沿着指定的轴(axis)进行计算。

常用的聚合函数:

  • sum(): 求和
  • mean(): 平均值
  • std(): 标准差
  • var(): 方差
  • min(): 最小值
  • max(): 最大值
  • argmin(): 最小值的索引
  • argmax(): 最大值的索引
  • cumsum(): 累积和
  • cumprod(): 累积积

“`python
arr = np.array([[1, 2, 3], [4, 5, 6]])

print(“Sum of all elements:”, arr.sum()) # 21
print(“Mean of all elements:”, arr.mean()) # 3.5

沿着 axis=0 (列) 求和

print(“Sum along axis 0:”, arr.sum(axis=0)) # [5 7 9] (第一列和, 第二列和, 第三列和)

沿着 axis=1 (行) 求平均值

print(“Mean along axis 1:”, arr.mean(axis=1)) # [2. 5.] (第一行平均, 第二行平均)

print(“Minimum element:”, arr.min()) # 1
print(“Maximum element index along axis 0:”, arr.argmax(axis=0)) # [1 1 1] (每列最大值所在的行索引)

arr_single = np.array([1, 2, 3, 4, 5])
print(“Cumulative sum:”, arr_single.cumsum()) # [ 1 3 6 10 15]
“`

理解 axis 参数至关重要:

  • axis=0 表示操作沿着第一个轴(行)进行,聚合结果会减少行的维度。
  • axis=1 表示操作沿着第二个轴(列)进行,聚合结果会减少列的维度。
  • 没有 axis 参数时,操作应用于所有元素。

6.4 矩阵/线性代数运算

NumPy 的 dot 函数或 @ 运算符用于执行矩阵乘法。np.linalg 模块提供了更丰富的线性代数功能。

“`python
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])

矩阵乘法

print(“Matrix multiplication (dot):\n”, np.dot(arr1, arr2))
print(“Matrix multiplication (@ operator):\n”, arr1 @ arr2)

矩阵的逆

matrix_to_invert = np.array([[1, 2], [3, 4]])
try:
inverse_matrix = np.linalg.inv(matrix_to_invert)
print(“Inverse matrix:\n”, inverse_matrix)
except np.linalg.LinAlgError:
print(“Matrix is singular and cannot be inverted.”)

矩阵的特征值和特征向量

eigenvalues, eigenvectors = np.linalg.eig(arr1)
print(“Eigenvalues:”, eigenvalues)
print(“Eigenvectors:\n”, eigenvectors)
“`

第七部分:广播 (Broadcasting)

广播是 NumPy 在不同形状的数组之间执行算术运算的一种机制。当两个数组的形状不同,但满足一定的广播规则时,较小的数组的形状会被“广播”到较大数组的形状,以便进行元素级运算。

广播规则:

  1. 如果两个数组的维度不同,则维度较少的数组的形状会在其前面填充 1,直到维度相同。
  2. 如果两个数组在任一维度上的大小相同,或者其中一个数组在该维度上的大小为 1,则认为它们在该维度上是兼容的。
  3. 如果两个数组在任一维度上的大小不同且都不为 1,则会引发错误。

“`python
arr = np.array([[1, 2, 3], [4, 5, 6]]) # 形状 (2, 3)
scalar = 10 # 形状 () -> 广播为 (1, 1) -> 再广播为 (2, 3)

print(arr + scalar)

输出:

[[11 12 13]

[14 15 16]]

vec = np.array([100, 200, 300]) # 形状 (3,) -> 广播为 (1, 3) -> 再广播为 (2, 3)
print(arr + vec)

输出:

[[101 202 303]

[404 505 606]] # vec 的每一列广播到 arr 的对应列

形状不兼容的例子

vec2 = np.array([10, 20]) # 形状 (2,)

print(arr + vec2) # ValueError: operands could not be broadcast together with shapes (2,3) (2,)

可以通过重塑或转置来使其兼容

vec2_reshaped = vec2.reshape((2, 1)) # 形状 (2, 1) -> 广播为 (2, 3)
print(arr + vec2_reshaped)

输出:

[[ 2 3 4]

[ 5 6 7]] # vec2_reshaped 的每一行广播到 arr 的对应行

“`

广播是 NumPy 高效性的关键之一,它避免了创建不必要的大内存副本来匹配形状。

第八部分:文件输入/输出

NumPy 可以方便地将数组保存到文件或从文件加载。

  • np.save('filename.npy', arr): 将数组以 .npy 格式保存(NumPy 特有的二进制格式)。
  • np.load('filename.npy'): 从 .npy 文件加载数组。
  • np.savetxt('filename.txt', arr, delimiter=','): 将数组保存为文本文件(如 CSV)。
  • np.loadtxt('filename.txt', delimiter=','): 从文本文件加载数组。

“`python
arr = np.arange(10).reshape(2, 5)

保存为 .npy 文件

np.save(‘my_array.npy’, arr)

从 .npy 文件加载

loaded_arr = np.load(‘my_array.npy’)
print(“Loaded from .npy:\n”, loaded_arr)

保存为文本文件 (CSV)

np.savetxt(‘my_array.csv’, arr, delimiter=’,’)

从文本文件加载

loaded_csv = np.loadtxt(‘my_array.csv’, delimiter=’,’)
print(“Loaded from .csv:\n”, loaded_csv)
“`

.npy 格式是 NumPy 推荐的方式,因为它能保留数组的 dtypeshape 信息,且读写速度快。.txt.csv 格式更易读,方便与其他工具共享数据,但可能需要手动处理数据类型和分隔符。

第九部分:性能优势:向量化 vs 循环

为了更直观地理解 NumPy 的性能优势,我们比较一下使用 Python 列表和 NumPy 数组进行简单运算(如数组相加)的速度。

“`python
import time

使用 Python 列表

list1 = list(range(1000000))
list2 = list(range(1000000))

start_time = time.time()
result_list = [x + y for x, y in zip(list1, list2)]
end_time = time.time()
print(f”Python list addition took: {end_time – start_time:.6f} seconds”)

使用 NumPy 数组

np_arr1 = np.arange(1000000)
np_arr2 = np.arange(1000000)

start_time = time.time()
result_np = np_arr1 + np_arr2 # 向量化操作
end_time = time.time()
print(f”NumPy array addition took: {end_time – start_time:.6f} seconds”)
“`

运行这段代码,你会发现 NumPy 数组的计算速度远远快于 Python 列表。这是因为 NumPy 的向量化操作是在底层 C 语言中执行的,而 Python 列表的循环是在解释器中执行。在实际应用中,尽量利用 NumPy 的向量化操作,避免显式的 Python 循环。

第十部分:高级主题与应用简介

掌握了以上内容,你已经具备了 NumPy 的核心使用能力。NumPy 还有一些更高级的功能和广泛的应用:

  • 随机数生成: np.random 模块提供了各种分布的随机数生成功能,对于模拟、统计分析非常有用。
    python
    # 生成 3x3 的服从标准正态分布的随机数
    rand_matrix = np.random.randn(3, 3)
    print(rand_matrix)
    # 生成 0 到 100 (不包含 100) 的随机整数,形状为 2x4
    rand_int_matrix = np.random.randint(0, 100, size=(2, 4))
    print(rand_int_matrix)
  • 排序与搜索: np.sort(), np.argsort() (返回排序后的索引), np.where() (根据条件返回满足条件的元素索引)。
    “`python
    arr = np.array([3, 1, 4, 1, 5, 9, 2, 6])
    print(“Sorted array:”, np.sort(arr))
    print(“Indices of sorted elements:”, np.argsort(arr)) # [1 3 6 0 2 4 7 5]

    print(“Indices where element > 3:”, np.where(arr > 3)) # (array([2, 4, 5, 7]),)

    结合索引使用

    print(“Elements > 3:”, arr[np.where(arr > 3)]) # [4 5 9 6]
    ``
    * **处理缺失数据:** NumPy 使用
    np.nan(Not a Number)表示缺失值。需要使用专门的函数(如np.isnan(),np.nanmean(),np.nan sum()`)来处理包含 NaN 的数组,因为标准的聚合函数遇到 NaN 会返回 NaN。
    * 与其他库集成:
    * Pandas: Pandas 的 DataFrame 和 Series 对象底层就是基于 NumPy 数组构建的。
    * SciPy: 提供了更高级的科学计算模块(优化、插值、信号处理等),它们的操作对象也是 NumPy 数组。
    * Matplotlib: 在 Matplotlib 中绘制数据时,通常使用 NumPy 数组作为输入。
    * Scikit-learn: 大部分机器学习算法的输入数据格式要求是 NumPy 数组。

熟练使用 NumPy 是进行 Python 数据科学、机器学习、科学计算等工作的基础。

第十一部分:总结与展望

NumPy 是 Python 数值计算领域的基石。通过本文的学习,你应该已经掌握了 NumPy 的核心概念和常用操作:

  • 理解 ndarray 的优势和基本属性。
  • 掌握数组的创建、索引、切片、布尔索引和花式索引。
  • 学会进行数组的形状操作、组合与分割。
  • 熟练运用元素级运算、通用函数和聚合函数。
  • 理解并利用广播机制。
  • 了解 NumPy 的文件 I/O。
  • 认识到 NumPy 向量化操作带来的巨大性能提升。
  • 对 NumPy 的高级功能和应用有了初步了解。

从入门到掌握是一个持续学习和实践的过程。掌握了 NumPy 的基本用法后,建议多进行实践,尝试解决一些实际的数值计算问题,深入了解 ufuncs 的更多功能,并结合其他库(如 Pandas、Matplotlib)进行更复杂的数据分析和可视化任务。

NumPy 的官方文档是学习和查阅的宝库,遇到问题时,查阅官方文档通常能找到最权威和详细的解答。

希望这篇文章能帮助你踏上 NumPy 的学习之路,并在未来的数据探索和计算工作中发挥它的强大威力!祝你学习愉快!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部