数据科学必备:numpy详解 – wiki基地


数据科学必备:NumPy 详解

在当今数据爆炸的时代,数据科学已成为驱动创新和决策的关键领域。而 Python 作为数据科学领域最受欢迎的编程语言之一,其强大之处不仅在于语言本身的易用性,更在于其丰富且高效的第三方库生态系统。在这其中,NumPy(Numerical Python)无疑是基石中的基石,是进行数值计算、数据分析以及构建更高级数据科学工具的必要前置条件。

本文将深入探讨 NumPy 的核心概念、主要功能以及它为何对于数据科学工作者来说是不可或缺的工具。

一、 NumPy 是什么?为什么它是数据科学的基石?

NumPy 是 Python 中用于科学计算的基础包。它提供了一个高性能的多维数组对象(ndarray),以及用于处理这些数组的工具。虽然 Python 内建的列表(list)可以存储不同类型的数据,并且非常灵活,但在处理大量同类型数值数据时,list 的效率远不及 NumPy 数组。

为什么 NumPy 如此重要?

  1. 高性能: NumPy 的核心 ndarray 对象采用 C 语言实现,这使得它在处理大型数组时具有极高的性能,远超 Python 的原生列表。数据科学常常涉及处理海量数据,性能是至关重要的考量。
  2. 内存效率: NumPy 数组存储同质数据(相同数据类型),内存布局紧凑且连续,这比 Python 列表存储异质数据(可以存储不同类型的对象引用)更加高效,尤其是在处理大数据时能显著减少内存占用。
  3. 强大的功能: NumPy 提供了大量的数学函数、线性代数操作、傅里叶变换、随机数生成等功能,这些都是数据科学、机器学习和科学计算中不可或缺的工具。
  4. 向量化操作: NumPy 允许对整个数组进行操作(称为向量化操作),而无需编写显式的循环。这不仅大大简化了代码,提高了开发效率,而且由于底层是优化过的 C 实现,执行速度也更快。
  5. 生态系统的基础: NumPy 是许多其他重要科学计算和数据科学库(如 Pandas、SciPy、Matplotlib、Scikit-learn、TensorFlow、PyTorch 等)的基础。这些库在底层都依赖于 NumPy 数组进行数据存储和操作。掌握 NumPy 是学习和使用这些库的前提。

简而言之,NumPy 为 Python 提供了一套高效处理数值数据的能力,正是这种能力使得 Python 能够胜任高性能计算和大规模数据处理的任务,从而成为数据科学的主流语言。

二、 NumPy 的核心:多维数组 ndarray

ndarray 是 NumPy 中最重要的数据结构。它代表一个具有相同数据类型的元素构成的多维同质数组。理解 ndarray 是掌握 NumPy 的关键。

2.1 ndarray 的基本属性

一个 ndarray 对象有几个重要的属性:

  • ndim: 数组的维数(轴的数量)。例如,一维数组 ndim 为 1,二维数组(矩阵) ndim 为 2。
  • shape: 一个表示数组各维度大小的元组。例如,一个 2 行 3 列的矩阵 shape(2, 3)
  • size: 数组中元素的总个数,等于 shape 中元素的乘积。
  • dtype: 数组中元素的数据类型。NumPy 支持多种数据类型,如 int64(64位整数)、float64(64位浮点数)、bool(布尔值)等。所有元素的 dtype 必须相同。
  • itemsize: 数组中每个元素占用的字节数。
  • data: 包含实际数组元素的缓冲区。

2.2 创建 ndarray

NumPy 提供了多种创建数组的方式:

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

使用 np.array() 函数可以将 Python 的列表或元组转换为 NumPy 数组。

“`python
import numpy as np

从列表创建一维数组

list_data = [1, 2, 3, 4, 5]
arr1d = np.array(list_data)
print(“一维数组:”)
print(arr1d)
print(“维数:”, arr1d.ndim)
print(“形状:”, arr1d.shape)
print(“类型:”, arr1d.dtype)

从嵌套列表创建二维数组

list_of_lists = [[1, 2, 3], [4, 5, 6]]
arr2d = np.array(list_of_lists)
print(“\n二维数组:”)
print(arr2d)
print(“维数:”, arr2d.ndim)
print(“形状:”, arr2d.shape)
print(“类型:”, arr2d.dtype)

创建指定数据类型的数组

arr_float = np.array([1, 2, 3], dtype=np.float64)
print(“\n指定浮点数类型的数组:”)
print(arr_float)
print(“类型:”, arr_float.dtype)
“`

2. 创建全零、全一或空数组:

  • np.zeros(shape): 创建指定形状和数据类型(默认为 float64)的全零数组。
  • np.ones(shape): 创建指定形状和数据类型(默认为 float64)的全一数组。
  • np.empty(shape): 创建指定形状和数据类型的空数组。数组中的元素是未初始化的,其值是内存中的任意值。

“`python

创建全零数组

zeros_arr = np.zeros((2, 3))
print(“\n全零数组 (2×3):”)
print(zeros_arr)

创建全一数组

ones_arr = np.ones((3, 2), dtype=np.int32) # 指定整数类型
print(“\n全一数组 (3×2, int32):”)
print(ones_arr)

创建空数组

empty_arr = np.empty((2, 2))
print(“\n空数组 (2×2):”)
print(empty_arr) # 注意:值是随机的
“`

3. 创建有序数列:

  • np.arange([start,] stop[, step,], dtype=None): 类似于 Python 的 range() 函数,创建等差数列,但不包含 stop 值。
  • np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None): 创建指定数量(num)的等差数列,包含 startstop 值。

“`python

使用 arange 创建数列

arr_range = np.arange(0, 10, 2) # 从0开始,小于10,步长为2
print(“\n使用 arange 创建的数列:”)
print(arr_range)

使用 linspace 创建数列

arr_linspace = np.linspace(0, 1, 5) # 在0和1之间创建5个点,包含0和1
print(“\n使用 linspace 创建的数列:”)
print(arr_linspace)
“`

4. 创建随机数数组:

np.random 模块提供了多种创建随机数数组的函数。

  • np.random.rand(d0, d1, ..., dn): 创建指定形状的 [0, 1) 之间均匀分布的随机数数组。
  • np.random.randn(d0, d1, ..., dn): 创建指定形状的标准正态分布(均值为0,方差为1)的随机数数组。
  • np.random.randint(low, high=None, size=None, dtype='l'): 创建指定范围内的随机整数数组。
  • np.random.random(size=None): 创建指定形状的 [0.0, 1.0) 之间均匀分布的随机浮点数数组 (与 rand 类似,但参数是元组)。

“`python

创建 3×3 的均匀分布随机数数组

rand_arr = np.random.rand(3, 3)
print(“\n3x3 均匀分布随机数数组:”)
print(rand_arr)

创建 2×4 的标准正态分布随机数数组

randn_arr = np.random.randn(2, 4)
print(“\n2x4 标准正态分布随机数数组:”)
print(randn_arr)

创建一个包含 10 个 1 到 100 之间的随机整数数组

randint_arr = np.random.randint(1, 101, size=10)
print(“\n包含 10 个 1-100 随机整数的数组:”)
print(randint_arr)
“`

三、 数组的索引和切片

访问和操作数组元素是 NumPy 的核心功能之一。NumPy 提供了灵活且强大的索引和切片方式。

3.1 基本索引和切片

与 Python 列表类似,可以使用方括号 [] 结合索引或切片来访问元素。对于多维数组,使用逗号 , 分隔各维度的索引或切片。

“`python
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(“原始二维数组:”)
print(arr)

访问单个元素 (行, 列)

print(“\n访问元素 (1, 2):”, arr[1, 2]) # 第2行第3列的元素 (索引从0开始)

切片:获取第一行

print(“\n获取第一行:”, arr[0, :]) # 或 arr[0]

切片:获取第三列

print(“\n获取第三列:”, arr[:, 2])

切片:获取子矩阵 (前两行,后两列)

print(“\n获取子矩阵 (前两行,后两列):”)
print(arr[:2, 1:])

使用步长进行切片

arr1d_step = np.arange(10)
print(“\n一维数组:”, arr1d_step)
print(“步长为2的切片:”, arr1d_step[::2]) # 从头到尾,步长为2
print(“逆序:”, arr1d_step[::-1]) # 逆序排列
“`

重要说明: 数组切片创建的是原数组的视图(view),而不是副本(copy)。这意味着修改切片的内容会影响原数组。如果需要独立的副本,应使用 .copy() 方法。

“`python
arr_slice = arr[:2, 1:]
print(“\n切片视图:”)
print(arr_slice)

修改切片中的元素

arr_slice[0, 0] = 99
print(“\n修改切片后,原数组:”)
print(arr) # 原数组也被修改了!

创建一个独立的副本

arr_copy = arr[:2, 1:].copy()
arr_copy[0, 0] = 100
print(“\n修改副本后,原数组:”)
print(arr) # 原数组未被修改
print(“副本:”)
print(arr_copy)
“`

3.2 布尔索引 (花式索引的一种)

布尔索引允许使用一个与数组形状相同的布尔数组来选择元素。布尔数组中为 True 的位置对应的原数组元素将被选中。这在数据过滤和选择时非常有用。

“`python
arr = np.array([10, 20, 30, 40, 50, 60])
print(“\n原始数组:”, arr)

创建一个布尔数组,选择大于30的元素

mask = arr > 30
print(“布尔掩码:”, mask)

使用布尔掩码进行索引

filtered_arr = arr[mask]
print(“过滤后的数组 (大于30):”, filtered_arr)

可以直接在索引中创建布尔表达式

print(“直接过滤 (小于等于40):”, arr[arr <= 40])

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

arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(“\n二维数组:\n”, arr2d)
print(“大于 5 的元素:”, arr2d[arr2d > 5]) # 返回一个一维数组
“`

3.3 整数数组索引 (花式索引的一种)

可以使用整数数组来选择任意顺序的元素子集。

“`python
arr = np.array([10, 20, 30, 40, 50])
print(“\n原始数组:”, arr)

使用索引列表选择元素

indices = [0, 3, 1]
selected_elements = arr[indices]
print(“使用索引列表选择的元素:”, selected_elements) # 结果是 [10, 40, 20]

在二维数组中使用整数数组索引

arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(“\n二维数组:\n”, arr2d)

选择 (0,0), (1,1), (2,2) 位置的元素

rows = np.array([0, 1, 2])
cols = np.array([0, 1, 2])
print(“对角线元素:”, arr2d[rows, cols]) # 结果是 [1 5 9]

选择 (0,1), (1,0), (2,1) 位置的元素

rows = np.array([0, 1, 2])
cols = np.array([1, 0, 1])
print(“指定位置元素:”, arr2d[rows, cols]) # 结果是 [2 4 8]

复制或重新排列行/列

print(“重复第0行和第2行:\n”, arr2d[[0, 2, 0]])
“`

四、 数组运算:向量化与广播

NumPy 真正的强大之处在于其向量化运算能力。它可以对整个数组执行元素级操作,而无需显式编写 Python 循环。此外,NumPy 的广播(Broadcasting)机制允许在不同形状的数组之间执行运算。

4.1 元素级运算

NumPy 数组之间的基本算术运算(加、减、乘、除、幂等)以及许多数学函数都是元素级的。

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

数组相加 (元素级)

print(“\n数组相加:”, arr1 + arr2) # [5 7 9]

数组相乘 (元素级)

print(“数组相乘:”, arr1 * arr2) # [ 4 10 18]

标量与数组相乘 (元素级)

print(“标量乘以数组:”, arr1 * 5) # [ 5 10 15]

数组开方 (元素级)

print(“数组开方:”, np.sqrt(arr2))

数组比较 (元素级)

print(“数组比较 (arr1 > arr2):”, arr1 > arr2) # [False False False]
“`

4.2 广播 (Broadcasting)

广播是 NumPy 中一个非常重要的概念,它描述了 NumPy 如何在不同形状的数组之间执行算术运算。当两个数组的形状不同,NumPy 会尝试自动调整其中一个或两个数组的形状,使它们兼容,然后进行元素级运算。这个过程类似于“广播”较小数组以匹配较大数组的形状,而无需实际复制数据。

广播遵循一套严格的规则,但最常见的场景可以概括为:

  1. 如果两个数组的维度数不同,那么将维度数较小的数组的 shape 前面补 1,直到它们的维度数相同。
  2. 沿维度大小为 1 的维度进行广播。
  3. 如果沿任何一个维度,两个数组的大小都不相等且都不为 1,则会引发错误。

常见广播示例:

  • 标量与数组运算: 标量可以被广播到任意形状的数组,与数组中的每个元素进行运算。

    python
    arr = np.array([[1, 2], [3, 4]])
    print("\n原始数组:\n", arr)
    print("数组 + 标量 10:\n", arr + 10)

  • 一维数组与二维数组运算: 一个一维数组(向量)可以与一个二维数组(矩阵)进行广播运算,前提是向量的长度与矩阵的某一维(通常是列)匹配。

    “`python
    matrix = np.array([[1, 2, 3], [4, 5, 6]]) # shape (2, 3)
    vector = np.array([10, 20, 30]) # shape (3,)

    vector 的 shape (3,) 会被广播成 (1, 3),然后沿轴 0 进行广播

    print(“\n矩阵 + 向量:\n”, matrix + vector)

    结果:

    [[1+10, 2+20, 3+30],

    [4+10, 5+20, 6+30]]

    ``
    如果向量的 shape 是
    (2,)并且你想让它加到矩阵的行上,你需要先将其转置或使用reshape使其 shape 变成(2, 1),NumPy 再将其广播到(2, 3)`。

    “`python
    vector_col = np.array([[10], [20]]) # shape (2, 1)
    print(“\n矩阵 + 列向量:\n”, matrix + vector_col)

    结果:

    [[1+10, 2+10, 3+10],

    [4+20, 5+20, 6+20]]

    “`

理解广播机制对于编写简洁高效的 NumPy 代码至关重要。

五、 线性代数操作

NumPy 的 np.linalg 模块提供了丰富的线性代数功能,这对于许多数据科学任务(如机器学习算法中的矩阵运算、数据降维等)非常重要。

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

矩阵乘法 (使用 @ 运算符 或 np.dot)

注意:这不是元素级乘法 (*)

print(“\n矩阵 A:\n”, A)
print(“矩阵 B:\n”, B)
print(“矩阵乘法 (A @ B):\n”, A @ B)
print(“矩阵乘法 (np.dot(A, B)):\n”, np.dot(A, B))

矩阵转置 (.T 属性)

print(“\n矩阵 A 的转置:\n”, A.T)

计算行列式

print(“\n矩阵 A 的行列式:”, np.linalg.det(A))

计算逆矩阵

try:
A_inv = np.linalg.inv(A)
print(“\n矩阵 A 的逆矩阵:\n”, A_inv)
# 验证 A @ A_inv 是否接近单位矩阵
print(“A @ A_inv:\n”, A @ A_inv) # 结果接近单位矩阵 (由于浮点数精度可能略有差异)
except np.linalg.LinAlgError:
print(“\n矩阵 A 是奇异矩阵,无法计算逆矩阵。”)

计算特征值和特征向量

eigenvalues, eigenvectors = np.linalg.eig(A)
print(“\n矩阵 A 的特征值:”, eigenvalues)
print(“矩阵 A 的特征向量:\n”, eigenvectors) # 每一列是一个特征向量
“`

np.linalg 模块还包括求解线性方程组、计算奇异值分解 (SVD)、计算范数等许多高级功能。

六、 统计分析

NumPy 提供了许多用于对数组进行描述性统计的函数。这些函数通常可以直接作为数组的方法调用,也可以作为 NumPy 的顶级函数调用。

“`python
data = np.array([10, 20, 30, 40, 50, 60])
print(“\n原始数据:”, data)

计算均值 (Mean)

print(“均值:”, np.mean(data)) # 或 data.mean()

计算中位数 (Median)

print(“中位数:”, np.median(data))

计算标准差 (Standard Deviation)

print(“标准差:”, np.std(data)) # 或 data.std()

计算方差 (Variance)

print(“方差:”, np.var(data)) # 或 data.var()

计算总和 (Sum)

print(“总和:”, np.sum(data)) # 或 data.sum()

计算最小值 (Minimum)

print(“最小值:”, np.min(data)) # 或 data.min()

计算最大值 (Maximum)

print(“最大值:”, np.max(data)) # 或 data.max()

计算累计和 (Cumulative Sum)

print(“累计和:”, np.cumsum(data))

计算累计积 (Cumulative Product)

print(“累计积:”, np.cumprod(data))
“`

处理多维数组的统计:axis 参数

对于多维数组,统计函数通常有一个 axis 参数,用于指定沿哪个轴进行计算。

  • axis=0: 沿列进行计算(垂直方向)。
  • axis=1: 沿行进行计算(水平方向)。
  • axis=None (默认): 计算整个数组的总和。

“`python
matrix = np.array([[1, 2, 3], [4, 5, 6]]) # shape (2, 3)
print(“\n二维数组:\n”, matrix)

计算整个数组的均值

print(“整个数组的均值:”, np.mean(matrix))

计算每列的均值 (axis=0)

print(“每列的均值:”, np.mean(matrix, axis=0)) # 结果 shape (3,) -> [ (1+4)/2, (2+5)/2, (3+6)/2 ]

计算每行的均值 (axis=1)

print(“每行的均值:”, np.mean(matrix, axis=1)) # 结果 shape (2,) -> [ (1+2+3)/3, (4+5+6)/3 ]

计算每列的总和

print(“每列的总和:”, np.sum(matrix, axis=0))

计算每行的最大值

print(“每行的最大值:”, np.max(matrix, axis=1))
``axis` 参数是 NumPy 统计和许多操作中非常重要的概念,理解它对于正确处理多维数据至关重要。

七、 数组形状操作

改变数组的形状、拼接或分割数组是数据准备和转换中常用的操作。

7.1 改变数组形状

  • reshape(shape): 返回一个具有新形状的数组,原数组数据不变。新形状必须与原数组的元素总数兼容。可以使用 -1 在新形状中代表一个由 NumPy 自动推断的维度。
  • ravel(): 返回一个扁平化(一维)的数组视图。
  • flatten(): 返回一个扁平化(一维)的数组副本。

“`python
arr = np.arange(12) # 一个包含 12 个元素的数组
print(“\n原始数组:”, arr)

改变形状为 3 行 4 列

reshaped_arr = arr.reshape((3, 4))
print(“\n改变形状为 (3, 4):\n”, reshaped_arr)

改变形状为 4 行 3 列

print(“\n改变形状为 (4, 3):\n”, arr.reshape((4, 3)))

使用 -1 推断维度 (例如,2行,列数自动计算)

print(“\n改变形状为 (2, -1):\n”, arr.reshape((2, -1)))

扁平化数组 (视图)

print(“\n扁平化 (ravel):”, reshaped_arr.ravel())

扁平化数组 (副本)

print(“扁平化 (flatten):”, reshaped_arr.flatten())
“`

7.2 拼接和分割数组

  • np.concatenate((arr1, arr2, ...), axis=0): 沿着指定轴将多个数组拼接起来。
  • np.vstack((arr1, arr2, ...)): 垂直(按行)堆叠数组(等同于 concatenate 沿着 axis=0)。
  • np.hstack((arr1, arr2, ...)): 水平(按列)堆叠数组(等同于 concatenate 沿着 axis=1)。
  • np.split(ary, indices_or_sections, axis=0): 将一个数组沿着指定轴分割成多个子数组。

“`python
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
print(“\narr1:\n”, arr1)
print(“arr2:\n”, arr2)

垂直拼接 (按行)

vstack_arr = np.vstack((arr1, arr2))
print(“\n垂直拼接 (vstack):\n”, vstack_arr)

水平拼接 (按列)

hstack_arr = np.hstack((arr1, arr2))
print(“\n水平拼接 (hstack):\n”, hstack_arr)

使用 concatenate 沿着 axis=0 拼接 (垂直)

concat_v = np.concatenate((arr1, arr2), axis=0)
print(“\n使用 concatenate 垂直拼接:\n”, concat_v)

使用 concatenate 沿着 axis=1 拼接 (水平)

concat_h = np.concatenate((arr1, arr2), axis=1)
print(“\n使用 concatenate 水平拼接:\n”, concat_h)

分割数组

arr_to_split = np.arange(16).reshape((4, 4))
print(“\n待分割数组:\n”, arr_to_split)

沿着 axis=0 平均分割成 2 块

split_rows = np.split(arr_to_split, 2, axis=0)
print(“\n沿行平均分割成 2 块:”)
for sub_arr in split_rows:
print(sub_arr)

沿着 axis=1 在指定索引处分割

split_cols = np.split(arr_to_split, [1, 3], axis=1) # 在索引 1 和 3 之前分割
print(“\n沿列在索引 [1, 3] 处分割:”)
for sub_arr in split_cols:
print(sub_arr)
“`

八、 NumPy 与其他库的集成

NumPy 不仅自身功能强大,更重要的是它构成了整个 Python 数据科学生态系统的底层。

  • Pandas: Pandas 的核心数据结构 DataFrameSeries 就是建立在 NumPy 数组之上的。Pandas 利用 NumPy 的高效数组操作来处理结构化数据。将 Pandas 数据转换为 NumPy 数组 (df.values) 或从 NumPy 数组创建 Pandas 对象 (pd.DataFrame(arr)) 是常见操作。
  • SciPy: SciPy 是一个更高级的科学计算库,它提供了 NumPy 没有的模块,如优化、积分、插值、信号处理、图像处理等。SciPy 的许多函数接受 NumPy 数组作为输入并返回 NumPy 数组。
  • Matplotlib: Matplotlib 是一个绘图库。它能够直接接受 NumPy 数组作为输入进行可视化,是绘制数据图表的常用工具。
  • Scikit-learn: Scikit-learn 是一个流行的机器学习库。其所有的算法都期望输入的数据是 NumPy 数组或 SciPy 稀疏矩阵。训练和预测的结果也通常是 NumPy 数组。
  • 深度学习框架 (TensorFlow, PyTorch): 这些框架中的张量(Tensor)对象在概念上和操作上与 NumPy 数组非常相似,并且提供了方便的函数用于 NumPy 数组和框架自带张量之间的相互转换。

因此,深入理解 NumPy 是有效使用这些高级库的前提。

九、 性能考量与向量化的重要性

前面多次提到 NumPy 的高性能,这主要归功于向量化和其底层实现

  • 向量化: 避免使用显式的 Python for 循环来处理数组元素。NumPy 提供的各种函数(如 np.sum(), arr + 5, np.linalg.eig(), arr[arr > 0]) 都是向量化操作。它们在底层是用优化的 C 或 Fortran 代码实现的,可以一次处理整个数组或数组的切片,避免了 Python 解释器带来的开销。
  • 底层实现: NumPy 的核心是用 C 实现的,这使得它能够直接操作内存,并且可以利用底层的并行化和 SIMD (Single Instruction, Multiple Data) 指令,极大地提高了计算速度。

对比 Python 列表和 NumPy 数组的性能差异 (示例概念,不实际运行复杂基准测试代码):

“`python

概念性示例,展示向量化 vs 循环

场景:将一个大数组中的每个元素都加 1

使用 Python 列表和循环 (慢)

large_list = list(range(1000000))

new_list = []

for item in large_list:

new_list.append(item + 1)

使用 NumPy 数组和向量化 (快)

large_arr = np.arange(1000000)

new_arr = large_arr + 1 # 向量化操作

“`
在处理大规模数据时,这种性能差异会变得非常显著。因此,在进行数据科学计算时,应尽量使用 NumPy 提供的向量化操作,而不是自己编写 Python 循环。

十、 总结

NumPy 是 Python 数据科学生态系统中不可或缺的基础库。它提供了一个高效的多维数组对象 ndarray,以及丰富的函数用于进行数值计算、线性代数、统计分析和数据操作。掌握 NumPy 的核心概念(ndarray、索引、切片、广播、向量化)是进行高效数据处理和分析的关键。

无论是进行简单的数据加载和预处理,还是构建复杂的机器学习模型,NumPy 都将是您最常用的工具之一。它是通往 Pandas、SciPy、Scikit-learn 等更高级库的必经之路。花时间深入学习和实践 NumPy 的各种功能,将极大地提升您在数据科学领域的效率和能力。

从创建数组到进行复杂的数学运算,从灵活的索引切片到强大的广播机制,NumPy 为 Python 带来了处理海量数值数据的“肌肉”。它是数据科学家的“瑞士军刀”,必备且强大。

通过本文的详细介绍,希望您对 NumPy 有了更深入的理解,并认识到它在数据科学中的核心地位。接下来,最重要的是动手实践,通过编写代码来巩固这些知识,并在实际项目中灵活运用 NumPy 的强大功能。

发表评论

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

滚动至顶部