NumPy 1.26 中文官方指南(二)(3)https://developer.aliyun.com/article/1510608
创建矩阵
你可以传递 Python 的列表列表来创建一个代表它们的 2-D 数组(或“矩阵”)在 NumPy 中表示。
>>> data = np.array([[1, 2], [3, 4], [5, 6]]) >>> data array([[1, 2], [3, 4], [5, 6]])
当你操纵矩阵时,索引和切片操作非常有用:
>>> data[0, 1] 2 >>> data[1:3] array([[3, 4], [5, 6]]) >>> data[0:2, 0] array([1, 3])
你可以像对向量进行聚合一样对矩阵进行聚合:
>>> data.max() 6 >>> data.min() 1 >>> data.sum() 21
你可以聚合矩阵中的所有值,并可以使用axis
参数跨列或行对它们进行聚合。 为了说明这一点,让我们看一个稍作修改的数据集:
>>> data = np.array([[1, 2], [5, 3], [4, 6]]) >>> data array([[1, 2], [5, 3], [4, 6]]) >>> data.max(axis=0) array([5, 6]) >>> data.max(axis=1) array([2, 5, 6])
创建了矩阵后,如果有两个大小相同的矩阵,你可以使用算术运算符对它们进行加法和乘法。
>>> data = np.array([[1, 2], [3, 4]]) >>> ones = np.array([[1, 1], [1, 1]]) >>> data + ones array([[2, 3], [4, 5]])
你可以对不同大小的矩阵进行这些算术运算,但前提是其中一个矩阵只有一列或一行。 在这种情况下,NumPy 将使用其广播规则进行操作。
>>> data = np.array([[1, 2], [3, 4], [5, 6]]) >>> ones_row = np.array([[1, 1]]) >>> data + ones_row array([[2, 3], [4, 5], [6, 7]])
请注意,当 NumPy 打印 N 维数组时,最后一个轴速度最快,而第一个轴速度最慢。 例如:
>>> np.ones((4, 3, 2)) array([[[1., 1.], [1., 1.], [1., 1.]], [[1., 1.], [1., 1.], [1., 1.]], [[1., 1.], [1., 1.], [1., 1.]], [[1., 1.], [1., 1.], [1., 1.]]])
常常有这样的情况,我们希望 NumPy 初始化数组的值。 NumPy 提供了ones()
和zeros()
之类的函数,以及用于随机数生成的random.Generator
类来实现。 你需要做的就是传入你想要生成的元素数量:
>>> np.ones(3) array([1., 1., 1.]) >>> np.zeros(3) array([0., 0., 0.]) >>> rng = np.random.default_rng() # the simplest way to generate random numbers >>> rng.random(3) array([0.63696169, 0.26978671, 0.04097352])
也可以使用ones()
,zeros()
和random()
来创建 2D 数组,如果给它们一个描述矩阵维度的元组:
>>> np.ones((3, 2)) array([[1., 1.], [1., 1.], [1., 1.]]) >>> np.zeros((3, 2)) array([[0., 0.], [0., 0.], [0., 0.]]) >>> rng.random((3, 2)) array([[0.01652764, 0.81327024], [0.91275558, 0.60663578], [0.72949656, 0.54362499]]) # may vary
阅读更多关于创建数组,填充0
、1
、其他值或未初始化的数组的内容,在 array creation routines 中。
生成随机数
随机数生成的使用是许多数值和机器学习算法的配置和评估的重要组成部分。无论是需要随机初始化人工神经网络中的权重,将数据分为随机集,还是随机洗牌数据集,能够生成随机数(实际上是可重复的伪随机数)是必不可少的。
使用Generator.integers
,你可以生成从低值(请记住这是 NumPy 中包含的值)到高值(不包含在内)的随机整数。你可以设置endpoint=True
使高值包含在内。
你可以生成一个 2 x 4 的随机整数数组,范围在 0 到 4 之间:
>>> rng.integers(5, size=(2, 4)) array([[2, 1, 1, 0], [0, 0, 0, 4]]) # may vary
在这里阅读更多关于生成随机数的内容。
如何获取唯一项和计数
本节介绍 np.unique()
你可以使用np.unique
轻松找到数组中的唯一元素。
例如,如果你从这个数组开始:
>>> a = np.array([11, 11, 12, 13, 14, 15, 16, 17, 12, 13, 11, 14, 18, 19, 20])
你可以使用np.unique
来打印出数组中的唯一值:
>>> unique_values = np.unique(a) >>> print(unique_values) [11 12 13 14 15 16 17 18 19 20]
要获取 NumPy 数组中唯一值的索引(数组中唯一值的第一个索引位置的数组),只需在np.unique()
中传递return_index
参数和你的数组。
>>> unique_values, indices_list = np.unique(a, return_index=True) >>> print(indices_list) [ 0 2 3 4 5 6 7 12 13 14]
你可以在np.unique()
中传递return_counts
参数和数组一起,以获取 NumPy 数组中唯一值的频次计数。
>>> unique_values, occurrence_count = np.unique(a, return_counts=True) >>> print(occurrence_count) [3 2 2 2 1 1 1 1 1 1]
这也适用于二维数组!如果你从这个数组开始:
>>> a_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [1, 2, 3, 4]])
你可以用以下方法找到唯一的值:
>>> unique_values = np.unique(a_2d) >>> print(unique_values) [ 1 2 3 4 5 6 7 8 9 10 11 12]
如果没有传递axis
参数,你的二维数组将被展开。
如果你想获取唯一的行或列,请确保传递axis
参数。要找到唯一的行,请指定axis=0
,要找到唯一的列,请指定axis=1
。
>>> unique_rows = np.unique(a_2d, axis=0) >>> print(unique_rows) [[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]]
要获取唯一的行、索引位置和出现次数,你可以使用:
>>> unique_rows, indices, occurrence_count = np.unique( ... a_2d, axis=0, return_counts=True, return_index=True) >>> print(unique_rows) [[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]] >>> print(indices) [0 1 2] >>> print(occurrence_count) [2 1 1]
要了解有关在数组中找到唯一元素的更多信息,请参阅unique
。
转置和重塑矩阵
本节介绍 arr.reshape()
,arr.transpose()
,arr.T
对于转置矩阵,经常需要转置矩阵。NumPy 数组具有允许你转置矩阵的属性T
。
在某些情况下,你可能也需要调换矩阵的维度。例如,当你的模型所期望的输入形状与你的数据集不同时,就需要这样做。这时reshape
方法就很有用。你只需要传入你想要给该矩阵的新维度即可。
>>> data.reshape(2, 3) array([[1, 2, 3], [4, 5, 6]]) >>> data.reshape(3, 2) array([[1, 2], [3, 4], [5, 6]])
你也可以使用.transpose()
根据你指定的值来反转或更改数组的轴。
如果你从这个数组开始:
>>> arr = np.arange(6).reshape((2, 3)) >>> arr array([[0, 1, 2], [3, 4, 5]])
你可以用arr.transpose()
转置你的数组。
>>> arr.transpose() array([[0, 3], [1, 4], [2, 5]])
你也可以使用arr.T
:
>>> arr.T array([[0, 3], [1, 4], [2, 5]])
要了解更多关于转置和重新塑形数组的信息,请参阅transpose
和 reshape
。
如何反转一个数组
本节涵盖 np.flip()
NumPy 的np.flip()
函数允许您沿着轴翻转或反转数组的内容。当使用np.flip()
时,请指定您想要翻转的数组和轴。如果您不指定轴,NumPy 将沿着输入数组的所有轴反转内容。
反转一维数组
如果你从这样一个一维数组开始:
>>> arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
你可以用以下方式反转它:
>>> reversed_arr = np.flip(arr)
如果你想打印你反转的数组,你可以运行:
>>> print('Reversed Array: ', reversed_arr) Reversed Array: [8 7 6 5 4 3 2 1]
反转二维数组
一个二维数组的工作方式基本相同。
如果你从这个数组开始:
>>> arr_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
你可以用以下方式反转所有行和所有列的内容:
>>> reversed_arr = np.flip(arr_2d) >>> print(reversed_arr) [[12 11 10 9] [ 8 7 6 5] [ 4 3 2 1]]
你可以只轻松地反转行:
>>> reversed_arr_rows = np.flip(arr_2d, axis=0) >>> print(reversed_arr_rows) [[ 9 10 11 12] [ 5 6 7 8] [ 1 2 3 4]]
或者只反转列:
>>> reversed_arr_columns = np.flip(arr_2d, axis=1) >>> print(reversed_arr_columns) [[ 4 3 2 1] [ 8 7 6 5] [12 11 10 9]]
你也可以只反转一个列或行的内容。例如,你可以反转索引位置为 1(第二行)的行的内容:
>>> arr_2d[1] = np.flip(arr_2d[1]) >>> print(arr_2d) [[ 1 2 3 4] [ 8 7 6 5] [ 9 10 11 12]]
你也可以反转索引位置为 1(第二列)的列:
>>> arr_2d[:,1] = np.flip(arr_2d[:,1]) >>> print(arr_2d) [[ 1 10 3 4] [ 8 7 6 5] [ 9 2 11 12]]
阅读有关反转数组的更多信息在flip
。
重新塑造和展平多维数组
本节涵盖 .flatten()
,ravel()
有两种常用的方法来展平一个数组:.flatten()
和 .ravel()
。两者之间的主要区别在于使用ravel()
创建的新数组实际上是对父数组的引用(即“视图”)。这意味着对新数组的任何更改都会影响父数组。由于ravel
不创建副本,因此它的内存效率高。
如果你从这个数组开始:
>>> x = np.array([[1 , 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
你可以使用flatten
将你的数组展平成一个一维数组。
>>> x.flatten() array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
当你使用flatten
时,对新数组的更改不会影响父数组。
例如:
>>> a1 = x.flatten() >>> a1[0] = 99 >>> print(x) # Original array [[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]] >>> print(a1) # New array [99 2 3 4 5 6 7 8 9 10 11 12]
但是当你使用ravel
时,你对新数组所做的更改将影响父数组。
例如:
>>> a2 = x.ravel() >>> a2[0] = 98 >>> print(x) # Original array [[98 2 3 4] [ 5 6 7 8] [ 9 10 11 12]] >>> print(a2) # New array [98 2 3 4 5 6 7 8 9 10 11 12]
在ndarray.flatten
中了解更多关于flatten
的信息,在ravel
中了解更多关于ravel
的信息。
如何访问更多信息的文档字符串
本节涵盖 help()
,?
,??
当涉及到数据科学生态系统时,Python 和 NumPy 是为用户而构建的。这中的一个最好的例子就是内置的文档访问。每个对象都包含对字符串的引用,这被称为文档字符串。在大多数情况下,这个文档字符串包含了关于对象以及如何使用它的快速而简洁的摘要。Python 有一个内置的 help()
函数,可以帮助您访问这些信息。这意味着几乎任何时候,您需要更多的信息,都可以使用 help()
快速找到您需要的信息。
例如:
>>> help(max) Help on built-in function max in module builtins: max(...) max(iterable, *[, default=obj, key=func]) -> value max(arg1, arg2, *args, *[, key=func]) -> value With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument.
因为访问附加信息非常有用,IPython 使用 ?
字符作为访问此文档以及其他相关信息的速记。IPython 是一个多语言交互计算的命令行壳。您可以在此处找到有关 IPython 的更多信息。
例如:
In [0]: max? max(iterable, *[, default=obj, key=func]) -> value max(arg1, arg2, *args, *[, key=func]) -> value With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. Type: builtin_function_or_method
甚至可以使用这种表示法来表示对象方法和对象本身。
假设你创建了这个数组:
>>> a = np.array([1, 2, 3, 4, 5, 6])
然后您可以获得许多有用的信息(首先关于 a
本身的细节,然后是 a
是其实例的 ndarray
的文档字符串):
In [1]: a? Type: ndarray String form: [1 2 3 4 5 6] Length: 6 File: ~/anaconda3/lib/python3.9/site-packages/numpy/__init__.py Docstring: <no docstring> Class docstring: ndarray(shape, dtype=float, buffer=None, offset=0, strides=None, order=None) An array object represents a multidimensional, homogeneous array of fixed-size items. An associated data-type object describes the format of each element in the array (its byte-order, how many bytes it occupies in memory, whether it is an integer, a floating point number, or something else, etc.) Arrays should be constructed using `array`, `zeros` or `empty` (refer to the See Also section below). The parameters given here refer to a low-level method (`ndarray(...)`) for instantiating an array. For more information, refer to the `numpy` module and examine the methods and attributes of an array. Parameters ---------- (for the __new__ method; see Notes below) shape : tuple of ints Shape of created array. ...
这对于您创建的函数和其他对象也是有效的。只需记住使用字符串文字 (""" """
或 ''' '''
将您的函数文档包含在您的函数中)。
例如,如果您创建了这个函数:
>>> def double(a): ... '''Return a * 2''' ... return a * 2
您可以获取有关该函数的信息:
In [2]: double? Signature: double(a) Docstring: Return a * 2 File: ~/Desktop/<ipython-input-23-b5adf20be596> Type: function
通过阅读您感兴趣的对象的源代码,您可以获得另一个级别的信息。使用双问号 (??
) 允许您访问源代码。
例如:
In [3]: double?? Signature: double(a) Source: def double(a): '''Return a * 2''' return a * 2 File: ~/Desktop/<ipython-input-23-b5adf20be596> Type: function
如果所讨论的对象是用 Python 以外的语言编译的,使用 ??
将返回与 ?
相同的信息。您会发现在许多内置对象和类型中都是如此,例如:
In [4]: len? Signature: len(obj, /) Docstring: Return the number of items in a container. Type: builtin_function_or_method
和:
In [5]: len?? Signature: len(obj, /) Docstring: Return the number of items in a container. Type: builtin_function_or_method
有相同的输出,因为它们是用 Python 以外的编程语言编译的。
使用数学公式
实现可以在数组上工作的数学公式的简便性是使 NumPy 在科学 Python 社区中被广泛使用的因素之一。
例如,这是均方误差公式(在处理回归的监督式机器学习模型中使用的一个核心公式):
在 NumPy 中实现这个公式简单而直接:
这样做的原因是 predictions
和 labels
可以包含一个或一千个值。它们只需要是相同的大小。
您可以这样可视化它:
在此示例中,预测和标签向量都包含三个值,这意味着n
的值为三。我们进行减法后,向量中的值被平方。然后 NumPy 对这些值求和,你的结果就是该预测的误差值和模型质量的得分。
如何保存和加载 NumPy 对象
这一部分涵盖了 np.save
,np.savez
,np.savetxt
,np.load
,np.loadtxt
在某些时候,你会想要将你的数组保存到磁盘并在不重新运行代码的情况下加载它们。幸运的是,有几种方法可以使用 NumPy 保存和加载对象。ndarray 对象可以通过处理普通文本文件的loadtxt
和savetxt
函数、处理带有 .npy 文件扩展名的 NumPy 二进制文件的load
和 save
函数以及处理带有**.npz**文件扩展名的 NumPy 文件的savez
函数来保存到磁盘文件中并从磁盘文件中加载。
.npy和**.npz**文件存储了重建 ndarray 所需的数据、形状、dtype 和其他信息的方式,使得即使文件在不同架构的另一台机器上,数组也可以被正确检索。
如果你想要存储一个单一的 ndarray 对象,可以使用np.save
将其保存为.npy 文件。如果你想要在单个文件中存储多个 ndarray 对象,可以使用np.savez
将其保存为.npz 文件。你还可以使用savez_compressed
将多个数组以压缩的 npz 格式保存到单个文件中。
使用np.save()
可以轻松保存和加载数组。只需确保指定你想要保存的数组和文件名即可。例如,如果你创建了这个数组:
>>> a = np.array([1, 2, 3, 4, 5, 6])
你可以使用以下命令将其保存为“filename.npy”:
>>> np.save('filename', a)
你可以使用np.load()
重构你的数组。
>>> b = np.load('filename.npy')
如果你想要检查你的数组,可以运行:
>>> print(b) [1 2 3 4 5 6]
你可以使用np.savetxt
将 NumPy 数组保存为普通文本文件,比如**.csv或.txt**文件。
例如,如果你创建了这个数组:
>>> csv_arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
你可以轻松将其保存为名为“new_file.csv”的.csv 文件:
>>> np.savetxt('new_file.csv', csv_arr)
你可以使用loadtxt()
快速且轻松地加载你保存的文本文件:
>>> np.loadtxt('new_file.csv') array([1., 2., 3., 4., 5., 6., 7., 8.])
savetxt()
和loadtxt()
函数接受额外的可选参数,如头部、尾部和分隔符。虽然文本文件更容易共享,但.npy 和.npz 文件更小且读取速度更快。如果你需要更复杂的文本文件处理(例如,如果需要处理包含缺失值的行),你会想要使用genfromtxt
函数。
使用savetxt
,你可以指定头部、尾部、注释等额外的可选参数。
在这里了解更多关于输入和输出例程。
导入和导出 CSV
很容易读取包含现有信息的 CSV 文件。这样做的最佳、最简单的方式是使用Pandas。
>>> import pandas as pd >>> # If all of your columns are the same type: >>> x = pd.read_csv('music.csv', header=0).values >>> print(x) [['Billie Holiday' 'Jazz' 1300000 27000000] ['Jimmie Hendrix' 'Rock' 2700000 70000000] ['Miles Davis' 'Jazz' 1500000 48000000] ['SIA' 'Pop' 2000000 74000000]] >>> # You can also simply select the columns you need: >>> x = pd.read_csv('music.csv', usecols=['Artist', 'Plays']).values >>> print(x) [['Billie Holiday' 27000000] ['Jimmie Hendrix' 70000000] ['Miles Davis' 48000000] ['SIA' 74000000]]
使用 Pandas 导出数组同样简单。如果您是 NumPy 的新手,您可能希望从数组的值中创建一个 Pandas 数据帧,然后用 Pandas 将数据帧写入 CSV 文件。
如果你创建了这个数组“a”
>>> a = np.array([[-2.58289208, 0.43014843, -1.24082018, 1.59572603], ... [ 0.99027828, 1.17150989, 0.94125714, -0.14692469], ... [ 0.76989341, 0.81299683, -0.95068423, 0.11769564], ... [ 0.20484034, 0.34784527, 1.96979195, 0.51992837]])
您可以创建一个 Pandas 数据帧
>>> df = pd.DataFrame(a) >>> print(df) 0 1 2 3 0 -2.582892 0.430148 -1.240820 1.595726 1 0.990278 1.171510 0.941257 -0.146925 2 0.769893 0.812997 -0.950684 0.117696 3 0.204840 0.347845 1.969792 0.519928
您可以轻松保存您的数据帧:
>>> df.to_csv('pd.csv')
并使用以下命令读取您的 CSV 文件:
>>> data = pd.read_csv('pd.csv')
您还可以使用 NumPy 的savetxt
方法保存数组。
>>> np.savetxt('np.csv', a, fmt='%.2f', delimiter=',', header='1, 2, 3, 4')
如果您使用命令行,随时可以通过像这样的命令读取已保存的 CSV 文件:
$ cat np.csv # 1, 2, 3, 4 -2.58,0.43,-1.24,1.60 0.99,1.17,0.94,-0.15 0.77,0.81,-0.95,0.12 0.20,0.35,1.97,0.52
或者您随时可以使用文本编辑器打开文件!
如果您有兴趣了解更多关于 Pandas 的信息,请查看官方 Pandas 文档。通过官方 Pandas 安装信息了解如何安装 Pandas。
用 Matplotlib 绘制数组
如果您需要为您的值生成一张图表,使用Matplotlib非常简单。
例如,您可能有这样一个数组:
>>> a = np.array([2, 1, 5, 7, 4, 6, 8, 14, 10, 9, 18, 20, 22])
如果您已经安装了 Matplotlib,可以用以下方法导入:
>>> import matplotlib.pyplot as plt # If you're using Jupyter Notebook, you may also want to run the following # line of code to display your code in the notebook: %matplotlib inline
要绘制您的值,您只需运行:
>>> plt.plot(a) # If you are running from a command line, you may need to do this: # >>> plt.show()
例如,您可以这样绘制一个一维数组:
>>> x = np.linspace(0, 5, 20) >>> y = np.linspace(0, 10, 20) >>> plt.plot(x, y, 'purple') # line >>> plt.plot(x, y, 'o') # dots
通过 Matplotlib,您可以获得大量的可视化选项。
>>> fig = plt.figure() >>> ax = fig.add_subplot(projection='3d') >>> X = np.arange(-5, 5, 0.15) >>> Y = np.arange(-5, 5, 0.15) >>> X, Y = np.meshgrid(X, Y) >>> R = np.sqrt(X**2 + Y**2) >>> Z = np.sin(R) >>> ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis')
要了解更多关于 Matplotlib 及其功能的信息,请查看官方文档。有关安装 Matplotlib 的指导,请参阅官方的安装部分。
图片来源:Jay Alammar http://jalammar.github.io/