当前位置:  首页>> 技术小册>> PyTorch深度学习实战

02 | NumPy(上):核心数据结构详解

在深度学习与科学计算的广阔领域中,NumPy(Numerical Python)无疑是一座不可或缺的基石。作为Python的一个扩展库,NumPy提供了高性能的多维数组对象以及操作这些数组的工具,使得在Python中处理大规模数值数据变得既快速又简单。本章“NumPy(上):核心数据结构详解”将深入探索NumPy的核心——多维数组(ndarray),理解其基础概念、创建方式、基本属性及操作方法,为后续利用NumPy进行高效数据处理和机器学习模型构建打下坚实基础。

一、NumPy简介与安装

NumPy是Python的一个开源数值计算扩展库,它提供了大量的数学函数库以及对数组的支持,特别是大量的维度数组与矩阵运算能力,此外也针对数组运算提供大量的数学函数库。NumPy的底层使用C语言编写,这使得其执行效率远高于纯Python代码。

安装NumPy

在Python环境中安装NumPy非常简单,可以通过pip命令进行安装:

  1. pip install numpy

安装完成后,即可在Python代码中通过import numpy as np来引入NumPy库,并习惯性地使用np作为别名。

二、NumPy的核心:ndarray

NumPy的核心数据结构是ndarray(N-dimensional array,即N维数组),它是一个固定大小的同类型元素数组。与Python内置的列表(list)相比,ndarray在存储效率和操作速度上具有显著优势,因为ndarray在内存中连续存储数据,且所有元素类型相同,这使得NumPy能够利用底层C语言库进行高效的数组操作。

2.1 ndarray的创建

NumPy提供了多种创建ndarray的方法,包括但不限于以下几种:

  • 使用np.array():从Python列表或元组等创建ndarray。

    1. import numpy as np
    2. arr = np.array([1, 2, 3, 4, 5])
    3. print(arr) # 输出:[1 2 3 4 5]
  • 使用np.zeros()np.ones():分别创建指定形状的全0和全1数组。

    1. zeros_arr = np.zeros((3, 4)) # 创建一个3x4的全0数组
    2. ones_arr = np.ones((2, 3)) # 创建一个2x3的全1数组
  • 使用np.arange():类似于Python的range()函数,但返回的是ndarray。

    1. arange_arr = np.arange(10) # 类似于range(10),但返回ndarray
  • 使用np.linspace():在指定区间内返回均匀间隔的数字组成的数组。

    1. linspace_arr = np.linspace(0, 10, 5) # 从0到10等间距生成5个数
  • 使用np.random.rand(), np.random.randn(), np.random.randint():生成随机数组。

    1. rand_arr = np.random.rand(3, 4) # 生成3x4的[0, 1)区间均匀分布的随机数组
    2. randn_arr = np.random.randn(2, 2) # 生成2x2的标准正态分布随机数组
    3. randint_arr = np.random.randint(1, 10, size=(2, 3)) # 生成2x3的[1, 10)区间随机整数数组
2.2 ndarray的基本属性

了解ndarray的基本属性对于有效操作数组至关重要。主要属性包括:

  • ndim:数组的维度。

    1. print(arr.ndim) # 对于一维数组,输出1
  • shape:数组的维度大小,返回一个元组。

    1. print(zeros_arr.shape) # 输出:(3, 4)
  • size:数组中的元素总数。

    1. print(zeros_arr.size) # 输出:12
  • dtype:数组中元素的类型。

    1. print(arr.dtype) # 默认为int64,根据输入数据自动推断
  • itemsize:数组中每个元素的大小(以字节为单位)。

    1. print(arr.itemsize) # 输出根据dtype而定,如int64则为8
2.3 ndarray的基本操作

NumPy提供了丰富的数组操作方法,这些操作大大简化了数据处理的复杂度,提高了处理效率。以下是一些基本操作的示例:

  • 索引与切片:与Python列表类似,但支持多维索引。

    1. print(zeros_arr[0, :]) # 输出第一行的所有元素
    2. print(rand_arr[:, 1]) # 输出所有行的第二列
  • 算术运算:对数组进行加、减、乘、除等运算时,NumPy会进行元素级别的操作(广播机制除外)。

    1. add_arr = rand_arr + 10 # 每个元素加10
    2. sub_arr = rand_arr - rand_arr[:, 0:1] # 列减去对应行的第一个元素
  • 广播机制:当两个数组的形状不一致时,NumPy能够自动扩展(broadcast)较小数组的形状,以便进行元素级操作。

    1. a = np.array([[1, 2], [3, 4]])
    2. b = np.array([10, 20])
    3. print(a + b) # 广播机制,b被扩展为[[10, 20], [10, 20]]
  • 聚合操作:如求和、平均值、最大值、最小值等。

    1. print(rand_arr.sum()) # 所有元素的和
    2. print(rand_arr.mean()) # 所有元素的平均值
    3. print(rand_arr.max()) # 所有元素中的最大值
    4. print(rand_arr.argmax()) # 最大值所在位置的索引
  • 排序与搜索:NumPy提供了多种排序和搜索数组元素的函数。

    1. sorted_arr = np.sort(rand_arr) # 对数组进行排序
    2. indices = np.argsort(rand_arr) # 返回排序后元素的索引
    3. value_index = np.where(rand_arr == rand_arr.max())[0][0] # 搜索最大值的位置
  • 数组重塑与转置:改变数组的形状而不改变其数据。

    1. reshaped_arr = rand_arr.reshape((3, -1)) # 重塑数组,-1表示自动计算该维度大小
    2. transposed_arr = rand_arr.T # 数组转置

三、总结

本章详细介绍了NumPy的核心数据结构——ndarray,包括其创建方式、基本属性以及一系列基本操作方法。NumPy的ndarray不仅为科学计算和数据分析提供了强大的工具,更是深度学习框架(如PyTorch、TensorFlow)底层实现的重要基础。通过深入理解ndarray,读者将能够更好地利用NumPy进行高效的数据预处理和特征工程,为后续深度学习模型的构建与优化奠定坚实的基础。在后续章节中,我们将继续探讨NumPy的高级特性,如广播机制、数组迭代、内存管理等,以及如何利用NumPy与PyTorch等深度学习框架协同工作,共同推进数据科学与人工智能领域的发展。