概述
NumPy(Numerical Python)是Python科学计算的核心库之一,用于处理大型、多维数组和矩阵,以及执行数值计算任务。它是Python生态系统中最重要的数据科学工具之一,并广泛用于科学、工程、数据分析和机器学习等领域。
下面是NumPy的一些主要功能和特点:
-
多维数组对象(ndarray):NumPy最重要的特性是ndarray对象,它是一个高效、灵活的多维数组容器。ndarray提供了快速的数值运算和广播功能,能够高效地存储和操作大量数据。
-
广播功能:NumPy的广播功能使得不同形状的数组之间的运算变得简单和高效。它可以自动处理不同维度的数组,使得它们的形状兼容,并在计算中按元素进行操作。
-
向量化操作:NumPy支持向量化操作,即可以直接对整个数组或数组的元素进行操作,而不需要使用循环。这种向量化操作可以提高计算效率,并简化代码。
-
数值计算函数:NumPy提供了许多常用的数值计算函数,如三角函数、指数函数、对数函数、线性代数运算、傅里叶变换等。这些函数对于科学计算和数据分析非常有用。
-
随机数生成:NumPy包含了一个强大的随机数生成器(numpy.random),可以生成各种概率分布的随机数。这对于模拟和随机抽样等任务非常有用。
-
索引和切片:NumPy支持灵活的索引和切片操作,可以快速访问数组的元素和子数组。这使得数据的提取和处理变得非常方便。
-
性能优化:NumPy底层使用C语言编写,并使用了优化的算法和数据结构,因此在处理大规模数据时具有较高的执行效率。此外,NumPy可以与其他编译型语言(如C、C++和Fortran)进行交互,进一步提高性能。
除了上述功能,NumPy还提供了许多其他工具和函数,用于数组操作、线性代数、傅里叶分析、图像处理等方面的任务。它还与其他科学计算库(如SciPy、Pandas和Matplotlib)紧密集成,形成了一个强大的科学计算生态系统。总之他是一个强大,应用非常广泛的模块,接下来主要参考他的官方文档,一步步探索numpy
起步
安装numpy,他和别的模块安装没有什么区别,使用pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple 这里需要注意的是使用国内源
导入 import numpy as np
简单使用
print(np.__version__)
a = np.arange(6)
print(a)
a2 = a[np.newaxis,]
print(a2)
- 创建了一个名为
a
的一维数组,其中包含从0到5的整数。np.arange(6)
函数用于生成一个数组,它包含了从0到6(不包括6)的整数,步长为1。然后,通过print(a)
语句将数组a
打印出来。 -
创建了一个新的数组
a2
,它是通过将数组a
添加一个新的维度来生成的。np.newaxis
用于添加新的轴,这里将其放在a
的索引位置上。在这种情况下,a[np.newaxis,]
的结果是一个形状为(1, 6)
的二维数组,其中第一个维度的大小为1,第二个维度的大小为6。然后,通过print(a2)
语句将数组a2
打印出来。请注意,
np.newaxis
的作用是为数组添加一个新的长度为1的维度,以便在进行广播等操作时使用。它可以用于扩展数组的维度。
输出结果为
1.21.5
[0 1 2 3 4 5]
[[0 1 2 3 4 5]]
另外我们安装numpy版本号为1.21.5,使用文档可以参考 NumPy: the absolute basics for beginners — NumPy v1.25 Manual
数组
数组是NumPy中的核心数据结构,它可以具有不同的维度和形状。在NumPy中,数组被称为ndarray(N-dimensional array),可以表示一维、二维或更高维的数据结构。
数组的维度可以理解为轴的数量,可以是一维、二维、三维,或者更高。一维数组可以被视为向量,没有行列之分。二维数组可以被视为矩阵,具有行和列的概念。对于三维及更高维的数组,通常使用术语"张量"来描述。
数组具有固定的大小,并且由相同类型和大小的元素组成。它的形状是一个非负整数的元组,表示每个维度的大小。通过索引和切片操作,可以访问和修改数组的元素。需要注意的是,不同的数组可以共享相同的数据,因此在一个数组上的修改可能会在其他数组中可见。
NumPy数组的属性提供了关于数组本身的信息,例如形状、维度等。通过访问这些属性,我们可以获取数组的特征信息,而无需创建新的数组对象。
创建数组
NumPy提供了一些函数来创建特定类型的数组。
从列表创建一个数组
import numpy as np
a = np.array([1, 2, 3])
下图是简单图示(实际比这发杂)
也可以创建一个随机数数组
import numpy as np
arr = np.random.rand(3, 3) # 创建一个3x3的随机数组
print(arr)
--------------------------------------------------
输出
[[0.70269926 0.01845552 0.00582304]
[0.04111886 0.66965589 0.30868907]
[0.40077769 0.34447327 0.2841275 ]]
--------------------------------------------------
补充一点数组常用的属性
-
ndarray.shape: 返回一个元组,表示数组的维度。对于n维数组,shape的长度为n,每个元素表示对应维度的大小。例如,对于一个2维数组,shape为
(m, n)
,其中m和n分别表示行数和列数。 -
ndarray.ndim: 返回数组的维度数。对于一个n维数组,ndim的值为n。
-
ndarray.size: 返回数组的元素总数。它等于数组的shape中各个维度大小的乘积。
-
ndarray.dtype: 返回数组中元素的数据类型。NumPy支持多种数据类型,包括整数、浮点数、布尔值等。
-
ndarray.itemsize: 返回数组中每个元素的字节大小。例如,对于一个
int32
类型的数组,itemsize
的值为4,因为int32
类型占用4个字节。 -
ndarray.data: 返回数组的内存缓冲区地址。通常情况下,我们不直接使用这个属性,而是通过索引和切片操作访问数组元素。
import numpy as np
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(对于int64类型,每个元素占用8个字节)
一些数组创建方法
numpy.zeros(shape, dtype=None, order='C')
:创建全零数组。numpy.ones(shape, dtype=None, order='C')
:创建全一数组。numpy.arange(start, stop, step, dtype=None)
:创建等差数列的数组。numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
:创建指定间隔的数组。
数组操作
numpy.concatenate()
: 沿指定轴连接数组。numpy.split()
: 沿指定轴将数组分割为多个子数组。numpy.copy()
: 创建数组的副本。numpy.sort()
: 对数组进行排序。numpy.unique()
: 返回数组中的唯一元素。numpy.reshape()
: 改变数组的形状。
数组索引和切片
我们可以使用python list 类似的方法对numpy数组进行索引和切片
import numpy as np
data = np.array([1, 2, 3])
print(data[1])
print(data[0:2])
print(data[1:])
print(data[-2:])
当你希望从数组中选择一部分或特定的数组元素进行进一步分析或额外操作时,你可以使用子集、切片和/或索引。
如果你想要选择满足特定条件的数组值,使用NumPy是很简单的。
数组运算
numpy数组运算,主要是对应元素分别计算,如你可以使用下面完成数组相加
data = np.array([1, 2])
ones = np.ones(2, dtype=int)
print(data + ones) #[2 3]
其他操作也类似
data - ones
data * data
data / data
如下为numpy提供的基础数学计算
基本数学函数:
numpy.add(x1, x2[, out])
:对两个数组的对应元素进行相加。numpy.subtract(x1, x2[, out])
:对两个数组的对应元素进行相减。numpy.multiply(x1, x2[, out])
:对两个数组的对应元素进行相乘。numpy.divide(x1, x2[, out])
:对两个数组的对应元素进行相除。numpy.power(x1, x2[, out])
:计算数组的幂。numpy.sqrt(x[, out])
:计算数组的平方根。numpy.exp(x[, out])
:计算数组的指数。numpy.log(x[, out])
:计算数组的自然对数。numpy.log10(x[, out])
:计算数组的以10为底的对数。numpy.sin(x[, out])
:计算数组的正弦值。numpy.cos(x[, out])
:计算数组的余弦值。numpy.tan(x[, out])
:计算数组的正切值。numpy.arcsin(x[, out])
:计算数组的反正弦值。numpy.arccos(x[, out])
:计算数组的反余弦值。numpy.arctan(x[, out])
:计算数组的反正切值。
广播
NumPy的广播(broadcasting)是一种机制,它允许不同形状的数组进行算术运算,而无需显式地将它们的形状调整为相同的形状。广播功能使得在处理不同大小和形状的数组时更加方便和高效。
广播的原理是通过自动处理数组的形状,使得它们能够在特定维度上进行元素级别的运算。在广播中,较小的数组会被自动扩展以匹配较大数组的形状,以便进行元素级别的运算。这使得我们可以对不同形状的数组执行一致的操作,而无需显示地进行形状调整。
广播遵循一组规则,用于确定如何自动调整数组的形状。这些规则是:
- 如果两个数组的维度数不同,那么维度较小的数组会通过在前面添加长度为1的维度来扩展其形状。
- 如果两个数组的维度数相同,但某个维度的长度不匹配,那么长度为1的维度将被拉伸以匹配另一个数组的形状。
- 如果两个数组在某个维度上的长度不同且不为1,那么广播将会失败,产生一个错误。
通过广播,我们可以方便地对不同大小和形状的数组进行运算,而无需显式地调整它们的形状。这在处理大规模数据、进行矩阵计算和向量化操作时特别有用。
以下是一个简单的广播示例:
import numpy as np
# 创建一个3x3的数组
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 创建一个1x3的数组
b = np.array([1, 2, 3])
# 广播运算
result = a + b
print(result)
输出结果
[[ 2 4 6]
[ 5 7 9]
[ 8 10 12]]
在这个例子中,我们对一个3x3的数组a
和一个1x3的数组b
进行了加法运算。由于数组b
的形状不匹配,广播机制自动将b
扩展为3x3的形状,使得它与a
的形状匹配,然后进行元素级别的运算。
通过广播机制,我们可以以一致的方式处理不同形状的数组,从而简化了代码并提高了计算效率。
存储和加载
NumPy提供了几种方式用于数组的存储和加载,包括将数组保存到磁盘文件和从文件中加载数组。以下是一些常用的方法:
-
将数组保存到文件:
numpy.save(file, arr)
:将数组保存到以.npy为扩展名的二进制文件中。numpy.savez(file, *args, **kwds)
:将多个数组保存到以.npz为扩展名的压缩文件中。
-
从文件加载数组:
numpy.load(file, mmap_mode=None, allow_pickle=False, fix_imports=True, encoding='ASCII')
:从.npy或.npz文件中加载数组。
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
np.save('array.npy', arr)
arr = np.load('array.npy')
3、文本文件的存储和加载:
numpy.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', footer='', comments='# ', encoding=None)
:将数组保存到文本文件中。numpy.loadtxt(fname, dtype=float, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0)
:从文本文件中加载数组。