- 什么是 NumPy?
什么是 NumPy?
NumPy 是用于处理数组的 python 库。
它还拥有在线性代数、傅立叶变换和矩阵领域中工作的函数。
为什么 NumPy 比列表快?
与列表不同,NumPy 数组存储在内存中的一个连续位置,因此进程可以非常有效地访问和操纵它们。
这种行为在计算机科学中称为引用的局部性。
这是 NumPy 比列表更快的主要原因。它还经过了优化,可与最新的 CPU 体系结构一同使用。
NumPy 用哪种语言编写?
NumPy 是一个 Python 库,部分用 Python 编写,但是大多数需要快速计算的部分都是用 C 或 C ++ 编写的。
NumPy as np
NumPy 通常以 np 别名导入。
别名:在 Python 中,别名是用于引用同一事物的替代名称。
请在导入时使用 as 关键字创建别名:
import numpy as np
检查 NumPy 版本
版本字符串存储在 __version__ 属性中。
import numpy as np
print(np.__version__)
创建 NumPy ndarray 对象
NumPy 用于处理数组。 NumPy 中的数组对象称为 ndarray。
我们可以使用 array() 函数创建一个 NumPy ndarray 对象。
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(type(arr))
要创建 ndarray,我们可以将列表、元组或任何类似数组的对象传递给 array() 方法,然后它将被转换为 ndarray
数组中的维
数组中的维是数组深度(嵌套数组)的一个级别。
嵌套数组:指的是将数组作为元素的数组。
| arr = np.array(61) | 0-D 数组 | 0-D 数组,或标量(Scalars),是数组中的元素。数组中的每个值都是一个 0-D 数组。 | |
| arr = np.array([1, 2, 3, 4, 5, 6]) | 1-D 数组 | 其元素为 0-D 数组的数组,称为一维或 1-D 数组。 | |
| arr = np.array([[1, 2, 3], [4, 5, 6]]) | 2-D 数组 | 其元素为 1-D 数组的数组,称为 2-D 数组。 它们通常用于表示矩阵或二阶张量。 NumPy 有一个专门用于矩阵运算的完整子模块 numpy.mat。 |
|
| arr = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]]) | 3-D 数组 | 其元素为 2-D 数组的数组,称为 3-D 数组。 |
检查维数?
NumPy 数组提供了 ndim 属性,该属性返回一个整数,该整数会告诉我们数组有多少维。
print(a.ndim)
更高维的数组
数组可以拥有任意数量的维。在创建数组时,可以使用 ndmin 参数定义维数。
arr = np.array([1, 2, 3, 4], ndmin=5)
访问数组元素
数组索引等同于访问数组元素。
您可以通过引用其索引号来访问数组元素。
NumPy 数组中的索引以 0 开头,这意味着第一个元素的索引为 0,第二个元素的索引为 1,以此类推。
访问 2-D 数组
要访问二维数组中的元素,我们可以使用逗号分隔的整数表示元素的维数和索引。
裁切数组
python 中裁切的意思是将元素从一个给定的索引带到另一个给定的索引。
我们像这样传递切片而不是索引:[*start*:*end*]。
我们还可以定义步长,如下所示:[*start*:*end*:*step*]。
-
如果我们不传递 start,则将其视为 0。
-
如果我们不传递 end,则视为该维度内数组的长度。
-
如果我们不传递 step,则视为 1。
裁切 2-D 数组
从第二个元素开始,对从索引 1 到索引 4(不包括)的元素进行切片:
print(arr[1, 1:4])
NumPy 中的数据类型

检查数组的数据类型
NumPy 数组对象有一个名为 dtype 的属性,该属性返回数组的数据类型print(arr.dtype)
用已定义的数据类型创建数组
我们使用 array() 函数来创建数组,该函数可以使用可选参数:dtype,它允许我们定义数组元素的预期数据类型:
创建数据类型为 4 字节整数的数组:
arr = np.array([1, 2, 3, 4], dtype='i4')
转换已有数组的数据类型
更改现有数组的数据类型的最佳方法,是使用 astype() 方法复制该数组。
astype() 函数创建数组的副本,并允许您将数据类型指定为参数。
数据类型可以使用字符串指定,例如 'f' 表示浮点数,'i' 表示整数等。或者您也可以直接使用数据类型,例如 float 表示浮点数,int 表示整数。
import numpy as np
arr = np.array([1.1, 2.1, 3.1])
newarr = arr.astype('i')
print(newarr)
print(newarr.dtype)
数组副本 vs 视图
副本和视图之间的区别
副本和数组视图之间的主要区别在于副本是一个新数组,而这个视图只是原始数组的视图。
副本拥有数据,对副本所做的任何更改都不会影响原始数组,对原始数组所做的任何更改也不会影响副本。
视图不拥有数据,对视图所做的任何更改都会影响原始数组,而对原始数组所做的任何更改都会影响视图。
视图:
创建视图,更改原始数组,然后显示两个数组:
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
x = arr.view()
arr[0] = 61
print(arr)
print(x)
检查数组是否拥有数据
如上所述,副本拥有数据,而视图不拥有数据,但是我们如何检查呢?
每个 NumPy 数组都有一个属性 base,如果该数组拥有数据,则这个 base 属性返回 None。否则,base 属性将引用原始对象。print(x.base)
数组的形状
数组的形状是每个维中元素的数量。
获取数组的形状
NumPy 数组有一个名为 shape 的属性,该属性返回一个元组,每个索引具有相应元素的数量。
数组重塑
重塑意味着更改数组的形状。
数组的形状是每个维中元素的数量。通过重塑,我们可以添加或删除维度或更改每个维度中的元素数量。
从 1-D 重塑为 3-D
最外面的维度将具有 2 个数组,其中包含 3 个数组,每个数组包含 2 个元素:
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(2, 3, 2)
print(newarr)
我们可以重塑成任何形状吗?
是的,只要重塑所需的元素在两种形状中均相等。
返回副本还是视图?
检查返回的数组是副本还是视图:print(arr.reshape(2, 4).base)
上面的例子返回原始数组,因此它是一个视图。
未知的维
您可以使用一个“未知”维度。
这意味着您不必在 reshape 方法中为维度之一指定确切的数字。
传递 -1 作为值,NumPy 将为您计算该数字。注释:我们不能将 -1 传递给一个以上的维度。
展平数组
展平数组(Flattening the arrays)是指将多维数组转换为 1D 数组。
我们可以使用 reshape(-1) 来做到这一点。
数组迭代
迭代意味着逐一遍历元素。
当我们在 numpy 中处理多维数组时,可以使用 python 的基本 for 循环来完成此操作。
如果我们对 1-D 数组进行迭代,它将逐一遍历每个元素。
在 2-D 数组中,它将遍历所有行。
如果我们迭代一个 n-D 数组,它将逐一遍历第 n-1 维。
如需返回实际值、标量,我们必须迭代每个维中的数组。
迭代每个标量元素
使用 nditer() 迭代数组:迭代每个标量元素
for x in np.nditer(arr):
print(x)
迭代不同数据类型的数组
我们可以使用 op_dtypes 参数,并传递期望的数据类型,以在迭代时更改元素的数据类型。
NumPy 不会就地更改元素的数据类型(元素位于数组中),因此它需要一些其他空间来执行此操作,该额外空间称为 buffer,为了在 nditer() 中启用它,我们传参 flags=['buffered']。
for x in np.nditer(arr, flags=['buffered'], op_dtypes=['S']):
print(x)
以不同的步长迭代
我们可以使用过滤,然后进行迭代。
每遍历 2D 数组的一个标量元素,跳过 1 个元素:
for x in np.nditer(arr[:, ::2]):
print(x)
枚举迭代
枚举是指逐一提及事物的序号。
有时,我们在迭代时需要元素的相应索引,对于这些用例,可以使用 ndenumerate() 方法。
for idx, x in np.ndenumerate(arr):
print(idx, x)
数组连接
在 SQL 中,我们基于键来连接表,而在 NumPy 中,我们按轴连接数组。
我们传递了一系列要与轴一起连接到 concatenate() 函数的数组。如果未显式传递轴,则将其视为 0
沿着行 (axis=1) 连接两个 2-D 数组: (axis=0,则是沿着列连接)
import numpy as np
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
arr = np.concatenate((arr1, arr2), axis=1)
print(arr)
使用堆栈函数连接数组
堆栈与级联相同,唯一的不同是堆栈是沿着新轴完成的。
我们可以沿着第二个轴连接两个一维数组,这将导致它们彼此重叠,即,堆叠(stacking)。
arr = np.stack((arr1, arr2), axis=1)
沿行堆叠
NumPy 提供了一个辅助函数:hstack() 沿行堆叠。
arr = np.hstack((arr1, arr2))
沿列堆叠
NumPy 提供了一个辅助函数:vstack() 沿列堆叠。
arr = np.vstack((arr1, arr2))
沿高度堆叠(深度)
NumPy 提供了一个辅助函数:dstack() 沿高度堆叠,该高度与深度相同。
arr = np.dstack((arr1, arr2))
拆分
连接(Joining)是将多个数组合并为一个,拆分(Spliting)将一个数组拆分为多个。
我们使用 array_split() 分割数组,将要分割的数组和分割数传递给它。
将数组分为 3 部分:newarr = np.array_split(arr, 3)
提示:我们也有 split() 方法可用,但是当源数组中的元素较少用于拆分时,它将不会调整元素,如上例那样,array_split() 正常工作,但 split() 会失败。array_split()如果数组中的元素少于要求的数量,它将从末尾进行相应调整。
下面的例子还返回三个 2-D 数组,但它们沿行 (axis=1) 分割。newarr = np.array_split(arr, 3, axis=1)
另一种解决方案是使用与 hstack() 相反的 hsplit()。
提示:vsplit() 和 dsplit() 可以使用与 vstack() 和 dstack() 类似的替代方法。
数组搜索
您可以在数组中搜索(检索)某个值,然后返回获得匹配的索引。
要搜索数组,请使用 where() 方法。x = np.where(arr == 4)
#查找值为偶数的索引:
x = np.where(arr%2 == 0)
#查找值为奇数的索引:
x = np.where(arr%2 == 1)
搜索排序
有一个名为 searchsorted() 的方法,该方法在数组中执行二进制搜索,并返回将在其中插入指定值以维持搜索顺序的索引。
假定 searchsorted() 方法用于排序数组。
x = np.searchsorted(arr, 7)
#例子解释:应该在索引 1 上插入数字 7,以保持排序顺序。
#该方法从左侧开始搜索,并返回第一个索引,其中数字 7 不再大于下一个值。
#默认情况下,返回最左边的索引,但是我们可以给定 side='right',以返回最右边的索引。
排序
排序是指将元素按有序顺序排列。
有序序列是拥有与元素相对应的顺序的任何序列,例如数字或字母、升序或降序。
对数组进行排序:
print(np.sort(arr))
#注释:此方法返回数组的副本,而原始数组保持不变。
过滤
从现有数组中取出一些元素并从中创建新数组称为过滤(filtering)。
在 NumPy 中,我们使用布尔索引列表来过滤数组。
布尔索引列表是与数组中的索引相对应的布尔值列表。
如果索引处的值为 True,则该元素包含在过滤后的数组中;如果索引处的值为 False,则该元素将从过滤后的数组中排除。
随机
随机数并不意味着每次都有不同的数字。随机意味着无法在逻辑上预测的事物。
伪随机和真随机
计算机在程序上工作,程序是权威的指令集。因此,这意味着必须有某种算法来生成随机数。
如果存在生成随机数的程序,则可以预测它,因此它就不是真正的随机数。
通过生成算法生成的随机数称为伪随机数。
我们可以生成真正的随机数吗?
是的。为了在我们的计算机上生成一个真正的随机数,我们需要从某个外部来源获取随机数据。外部来源通常是我们的击键、鼠标移动、网络数据等。
我们不需要真正的随机数,除非它与安全性(例如加密密钥)有关或应用的基础是随机性(例如数字轮盘赌轮)。
在本教程中,我们将使用伪随机数。
生成随机数
NumPy 提供了 random 模块来处理随机数。x = random.randint(100)
生成随机浮点
random 模块的 rand() 方法返回 0 到 1 之间的随机浮点数。x = random.rand()
生成随机数组
在 NumPy 中,我们可以使用上例中的两种方法来创建随机数组。
randint() 方法接受 size 参数,您可以在其中指定数组的形状。x=random.randint(100, size=(5))
生成有 3 行的 2-D 数组,每行包含 5 个随机数:x = random.rand(3, 5)
从数组生成随机数
choice() 方法使您可以基于值数组生成随机值。 choice() 方法将数组作为参数,并随机返回其中一个值。
x = random.choice([3, 5, 7, 9])
ufuncs
ufuncs 指的是“通用函数”(Universal Functions),它们是对 ndarray 对象进行操作的 NumPy 函数。
