numpy reshape函数_数据处理利器NumPy初识(三)

回顾

在数据处理利器NumPy初识(二)中,我们介绍了NumPy中的几个常用函数,包括reshape()、resize()、copy()、astype()、stack()、split()等,以及ndarray的索引和切片的基本用法。今天我们看一下NumPy中对ndarray的数据运算和广播机制的相关内容。

ndarray数据运算

NumPy中ndarray的数据运算包括基本标量数据运算、向量矩阵内积计算和数据处理相关运算。

  • 基本标量数据运算

NumPy中ndarray的基本标量数据运算指的是在ndarray上以其中的元素方式进行计算,既可以用“+(加)、-(减)、*(乘)、/(除)、**(幂)”等数学运算符重载,也可以使用NumPy模块中的函数(add、subtract、multiply、divide等)。下面我们来看一下ndarray的一些基本标量数据运算。​​

import numpy as nparr = np.arange(12).reshape(3, 4)print(arr)print("---------------")# 加print(arr + 5)print(np.add(arr, 5))print("---------------")# 减print(arr - 5)print(np.subtract(arr, 5))print("---------------")# 乘print(arr * 5)print(np.multiply(arr, 5))print("---------------")# 除print(arr / 5)print(np.divide(arr, 5))print("---------------")# 幂print(arr ** 2)print("---------------")# 平方根print(np.sqrt(x))

我们创建一个3*4的ndarray,然后分别对它进行加、减、乘、除、幂、平方根的运算,可以看到,当ndarray与单个数进行标量数据运算时,ndarray中的每个元素分别与此数进行运算得到结果。同时,用数学符号和使用NumPy模块中的运算函数计算的结果是一致的。运行结果如下所示。

numpy reshape函数_数据处理利器NumPy初识(三)_第1张图片

ndarray与单个标量的运算

ndarray除了可以与单个数进行基本标量数据运算外,两个ndarray之间也可以进行基本标量数据运算,运算规则为ndarray中对应位置上的元素分别进行对应的运算。我们创建两个ndarray进行基本标量数据运算。​

import numpy as npx = np.array([[1,2],[3,4]], dtype=np.float64)y = np.array([[5,6],[7,8]], dtype=np.float64)# 加法print(x + y)print(np.add(x, y))print("---------------")# 减法print(x - y)print(np.subtract(x, y))print("---------------")# 乘法print(x * y)print(np.multiply(x, y))print("---------------")# 除法print(x / y)print(np.divide(x, y))print("---------------")# 幂print(x ** y)print("---------------")

两个ndarray中对应位置上的元素分别做对应运算,运行结果如下所示。

numpy reshape函数_数据处理利器NumPy初识(三)_第2张图片

ndarray与ndarray的标量运算

  • 向量矩阵内积计算

我们之前有提到,ndarray的元素之间是用空格隔开的,从结构上看,一个一维ndarray相当于一个向量,一个多维ndarray就相当于一个矩阵。事实上,在很多应用场景下,我们也经常把ndarray当做向量或矩阵来使用。学过向量与矩阵的朋友都知道,数学上的向量乘法、矩阵乘法是不同于标量乘法的,不是简单的对应位置上的元素做乘法。(关于向量与矩阵的概念以及向量乘法、矩阵乘法这里不做详细介绍,但这是比较重要的知识点,不了解或者已经遗忘的朋友请务必去学习回顾一下。)

不同于MATLAB,NumPy中“*”符号只是是标量乘法,而不是向量乘法、矩阵乘法,NumPy中的向量乘法、矩阵乘法使用dot()函数来计算,运算结果也成为向量或矩阵的内积。dot()函数也有两种使用方法,既可以作为ndarray对象的实例方法,也可以直接以NumPy模块中的函数作为运算。我们创建两个矩阵和两个向量,分别进行向量与向量的内积计算,向量与矩阵的内积计算,矩阵与矩阵的内积计算。​

import numpy as np# 创建两个矩阵x = np.array([[1,2],[3,4]])y = np.array([[5,6],[7,8]])# 创建两个向量v = np.array([9,10])w = np.array([11, 12])# 向量与向量的内积为标量print(v.dot(w.T))print(np.dot(v, w))print("---------------")# 矩阵与向量的内积为向量print(x.dot(v))print(np.dot(x, v))print("---------------")# 矩阵与矩阵的内积为矩阵print(x.dot(y))print(np.dot(x, y))

运算结果如下所示。向量与向量的内积结果为一个标量,向量与矩阵的内积结果为一个向量,矩阵与矩阵的内积结果为一个矩阵。

numpy reshape函数_数据处理利器NumPy初识(三)_第3张图片

向量、矩阵间的内积运算

  • 数据处理相关运算

NumPy中对于ndarray的数据处理运算提供了许多有用的函数,包括计算平均值的mean()函数、计算最大、最小值的max()、min()函数,计算标准差的std()函数、计算方差的var()函数、求总和的sum()函数、排序函数sort()等。这些运算函数的基本用法如下。​

import numpy as nparr = np.arange(12).reshape(3, 4)# 平均值print(arr.mean())print(np.mean(arr, axis=0))print("---------------")# 最大、最小值print(arr.max())print(np.max(arr, axis=1))print("---------------")print(arr.min())print("---------------")# 标准差print(arr.std())print("---------------")# 方差print(arr.var())print("---------------")# 求和print(arr.sum())print("---------------")# 排序print(np.sort(arr))print(-np.sort(-arr))

我们创建一个3*4的ndarray来进行数据处理运算。这些数据处理运算函数与dot()函数一样,也有两种使用方法,以mean()为例,我们可以使用arr.mean()或np.mean(),当不传参数时,默认操作对象为整个ndarray,设置axis=1或axis=0时可以分别指定对行或对列进行数据处理运算。运行结果如下所示。

numpy reshape函数_数据处理利器NumPy初识(三)_第4张图片

数据处理相关运算

NumPy中的广播

NumPy中的广播是一种非常强大的机制,它允许NumPy在执行数据运算时使用不同形状的数组。例如,当一个较小的ndarray和一个较大的ndarray要进行数据运算时,我们会希望通过多次使用较小的数组来对较大的数组执行一些操作。

在介绍基本标量数据运算时,我们用ndarray与一个标量进行运算,其实就是一个简单的广播,广播机制会把标量循环填充成与要运算的ndarray同样形状的一个ndarray,然后再运算,所以我们看到的结果就是ndarray中每个元素分别与标量进行相关运算。

如果没有广播机制,当ndarray与一个标量进行运算时,需要先对这个标量进行转化,我们可以来看一下这个过程。​

import numpy as npx = np.arange(12).reshape(3, 4)print(x)v = 5# 创建与x形状一致的空ndarrayy = np.empty_like(x)# 用标量5填充这个空ndarrayfor i in range(3): for j in range(4): y[i, j] = 5 print("---------------")print(y)# 运算print("---------------")print(np.add(x, y))

首先,创建一个与要运算的ndarray形状一致的空ndarray,然后用参与运算的标量去填充这个空ndarray,最后对这两个形状一致的ndarray进行运算。运行结果如下所示。

numpy reshape函数_数据处理利器NumPy初识(三)_第5张图片

循环扩充模拟广播

以上是一种保持ndarray形状一致的扩展方法,但是这种方法在ndarray非常大时,像这样的显式循环就会变得很慢。这时我们有另一种快速的扩展方法,使用NumPy的tile()函数进行叠加。 我们可以像如下这样实现这种方法。​

import numpy as npx = np.arange(12).reshape(3, 4)print(x)v = np.array([5])# 使用tile进行ndarray叠加vv = np.tile(v, (3, 4))print("---------------")print(vv)# 运算y = x + vvprint("---------------")print(y)

tile()函数传入要扩展的ndarray,然后将形状传入,就会开始往各个维度方向上进行扩展。运行结果如下所示,与循环方式填充实现的结果是一样的。

numpy reshape函数_数据处理利器NumPy初识(三)_第6张图片

tile()函数扩充模拟广播

以上是没有广播机制的前提下对较小的ndarray进行扩展填充至与较大的ndarray形状一致的方法,有了广播机制,就不需要以上的操作了,对于3*4的ndarray与标量5的运算,我们可以直接进行。​

import numpy as npx = np.arange(12).reshape(3, 4)print(x)v = 5# 直接运算y = x + vprint("---------------")print(y)

运算结果如下所示,可以得到一样的正确结果。

numpy reshape函数_数据处理利器NumPy初识(三)_第7张图片

广播机制运算

当然,需要注意的是,不是所有较小的ndarray与较大的ndarray之间的运算都是可以利用广播机制的,例如,我们用形状为(4,3)的ndarray与形状为(3,4)的ndarray进行数据运算,就会报“operands could not be broadcast together with shapes (4,3) (3,4)”的错误,可以看到,形状(4,3)和(3,4)的ndarray并不能顺利进行广播来运算。

因此,我们在使用广播机制时,一定要特别注意是否遵循了以下规则:

1、如果ndarray不具有相同的rank,则将较低等级ndarray的形状添加1,直到两个形状具有相同的长度。

2、如果两个ndarray在维度上具有相同的大小,或者如果其中一个ndarray在该维度中的大小为1,则称这两个ndarray在维度上是兼容的。

3、如果ndarray在所有维度上兼容,则可以一起广播。

4、广播之后,每个阵列的行为就好像它的形状等于两个输入ndarray的形状的元素最大值。

5、在一个ndarray的大小为1且另一个ndarray的大小大于1的任何维度中,第一个ndarray的行为就像沿着该维度复制一样。

形状(4,3)和(3,4)的ndarray就是由于没有遵循规则2,所以不能顺利进行广播。在遵循广播机制规则的基础下,我们应该尽可能地去使用它,因为广播机制通常会使我们的代码更加简洁,效率也更高。

总结

以上介绍了NumPy中的各种数据运算处理方法以及NumPy中广播机制的基本概念和用法。感谢大家的关注,欢迎批评指正,一起交流~

你可能感兴趣的:(numpy,reshape函数,numpy,平方,numpy,矩阵乘法,numpy矩阵乘法)