NumPy中的广播:对不同形状的数组进行操作

2021-01-12 14:46:09 浏览数 (1)

NumPy是用于Python的科学计算库。它是数据科学领域中许多其他库(例如Pandas)的基础。

在机器学习领域,无论原始数据采用哪种格式,都必须将其转换为数字数组以进行计算和分析。因此,需要对阵列进行快速,鲁棒和准确的计算,以对数据执行有效的操作。

NumPy是科学计算的主要库,因为它提供了我们刚刚提到的功能。在本文中,我们重点介绍正在广播的NumPy的特定类型的操作。

广播描述了在算术运算期间如何处理具有不同形状的数组。我们将通过示例来理解和练习广播的细节。

我们首先需要提到数组的一些结构特性。

维度:索引的数量

形状:数组在每个维度上的大小

大小:数组中元素的总数。

尺寸的计算方法是将每个维度的尺寸相乘。我们来做一个简单的例子。

代码语言:javascript复制
 import numpy as np
 arr = np.random.randint(10, size=(3,4))
 
 arr
 array([[7, 8, 9, 9],
        [6, 0, 2, 9],
        [3, 0, 8, 0]])
        
 arr.ndim
 2
 
 arr.shape
 (3,4)
 
 arr.size
 12

使用NumPy进行的算术运算通常按元素进行。例如,当我们相加两个数组时,在相同位置的元素被计算。

代码语言:javascript复制
 a = np.array([1,2,3,4])
 b = np.array([1,1,1,1])
 
 a   b
 array([2, 3, 4, 5])

因为操作是按元素执行的,所以数组必须具有相同的形状。广播在这种情况下提供了一些灵活性,因此可以对不同形状的数组进行算术运算。

但是有一些规则必须满足。我们不能只是广播任何数组。在下面的例子中,我们将探索这些规则以及广播是如何发生的。

最简单的广播形式发生在数组和标量相加时。

代码语言:javascript复制
 a = np.array([1,2,3,4])
 b = 1
 
 a   b
 array([2, 3, 4, 5])

做加法操作时,假设b是一个有4个整数为1的数组。

图中所示的拉伸只是概念上的。NumPy实际上并不对标量进行复制,以匹配数组的大小。相反,在加法中使用原始标量值。因此,广播操作在内存和计算方面非常高效。

我们还可以对高维数组和一个标量进行加法操作。在这种情况下,广播发生在所有坐标轴上。在下面的示例中,我们有一个形状为(3,4)的二维数组。标量被加到数组的所有元素中。

代码语言:javascript复制
 A = np.random.randint(5, size=(3, 4))
 B = 2
 print(A)
 print("--------")
 print(A   B)
 
 [[0 1 0 0]
  [0 2 4 3]
  [0 1 2 1]]
 --------
 [[2 3 2 2]
  [2 4 6 5]
  [2 3 4 3]]

本例中的广播如下:

广播规则

我们不能只是在算术运算中广播任何数组。如果阵列的尺寸兼容,则广播适用。在以下情况下被视作两个维度兼容:

每个维度的大小相等,或其中之一是1。

换句话说,如果维度中的大小不相等,则其中之一必须为1。

考虑以下示例。我们有几个二维数组。二维尺寸相等。但是,它们中的一个在第一维度上的大小为3,而另一个在大小上为1。因此,第二个数组将在广播中广播。

两个数组在两个维度上的大小可能不同。在这种情况下,将广播尺寸为1的尺寸以匹配该尺寸中的最大尺寸。

下图说明了这种情况的示例。第一个数组的形状是(4,1),第二个数组的形状是(1,4)。由于在两个维度上都进行广播,因此所得数组的形状为(4,4)。

当对两个以上的数组进行算术运算时,也会发生广播。同样的规则也适用于此。每个尺寸的大小必须相等或为1。

代码语言:javascript复制
 A = np.random.randint(5, size=(1,3,4))
 B = np.random.randint(5, size=(2,1,4))
 C = np.random.randint(5, size=(2,3,1))

所有这些阵列都是三维的。如果特定维度的大小与其他数组不同,则必须为1。

如果我们将这三个数组加在一起,则结果数组的形状将为(2,3,4),因为广播的尺寸为1的尺寸与该尺寸中的最大尺寸匹配。

代码语言:javascript复制
 print((A   B   C).shape)
 
 (2, 3, 4)

最后做一个简单总结

我们介绍了NumPy中广播的想法。使用数组执行算术计算时,它提供了灵活性。

广播还可以通过防止NumPy不必要地复制值来使某些操作在存储和计算方面更加高效。

感谢您的阅读。如果您有任何反馈意见,请告诉我。

作者:Soner Yıldırım

原文地址:https://towardsdatascience.com/broadcasting-arrays-with-numpy-753bb118bdc9

deephub翻译组

0 人点赞