专业编程基础技术教程

网站首页 > 基础教程 正文

Numpy快速入门教程(二):数据类型,数组计算,Broadcasting

ccvgpt 2024-10-12 13:29:34 基础教程 11 ℃

首先声明本篇博客是本人学习CS231n的学习笔记,分享给大家当作参考。原文请看本人博客http://blog.csdn.net/weixin_39449570/article/details/78606733

Numpy快速入门教程(二):数据类型,数组计算,Broadcasting

数据类型

每个Numpy数组都是数据类型相同的元素组成的网格。Numpy提供了很多的数据类型用于创建数组。当你创建数组的时候,Numpy会尝试猜测数组的数据类型,你也可以通过参数直接指定数据类型,例子如下:

```

>>> import numpy as np

>>> x = np.array([1, 2])

>>> print(x.dtype)

int32

>>> x = np.array([1.0,2.0])

>>> print(x.dtype)

float64

>>> x = np.array([1, 2], dtype=np.int64)

>>> print(x.dtype)

int64

```

详细介绍请查阅[Data type objects](https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html)

数组计算

基本数学计算函数会对数组中元素逐个进行计算,既可以利用操作符重载,也可以使用函数方式:

```

>>> import numpy as np

>>> x = np.array([[1,2],[3,4]], dtype=np.float64)

>>> y = np.array([[5,6],[7,8]], dtype=np.float64)

>>> print(x + y)

[[ 6. 8.]

[ 10. 12.]]

>>> print(np.add(x,y))

[[ 6. 8.]

[ 10. 12.]]

>>> print(x - y)

[[-4. -4.]

[-4. -4.]]

>>> print(np.subtract(x,y))

[[-4. -4.]

[-4. -4.]]

>>> print(x * y)

[[ 5. 12.]

[ 21. 32.]]

>>> print(np.multiply(x,y))

[[ 5. 12.]

[ 21. 32.]]

>>> print(x / y)

[[ 0.2 0.33333333]

[ 0.42857143 0.5 ]]

>>> print(np.divide(x,y))

[[ 0.2 0.33333333]

[ 0.42857143 0.5 ]]

>>> print(np.sqrt(x))

[[ 1. 1.41421356]

[ 1.73205081 2. ]]

```

和MATLAB不同,*是元素逐个相乘,而不是矩阵乘法。在Numpy中使用dot来进行矩阵乘法:

```

>>> 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))

219

>>> print(np.dot(v,w))

219

>>> print(x.dot(v))

[29 67]

>>> print(np.dot(x,v))

[29 67]

>>> print(x.dot(y))

[[19 22]

[43 50]]

>>> print(np.dot(x,y))

[[19 22]

[43 50]]

```

Numpy提供了很多计算数组的函数,其中最常用的一个是sum:

```

>>> import numpy as np

>>> x = np.array([[1,2],[3,4]])

>>> print(np.sum(x)) # Compute sum of all elements;

10

>>> print(np.sum(x,axis=0)) # Compute sum of each column

[4 6]

>>> print(np.sum(x,axis=1)) # Compute sum of each row

[3 7]

```

想要了解更多函数,可以查看[Mathematical functions](https://docs.scipy.org/doc/numpy/reference/routines.math.html)

除了计算,我们还常常改变数组或者操作其中的元素。其中将矩阵转置是常用的一个,在Numpy中,使用T来转置矩阵:

```

>>> import numpy as np

>>> x = np.array([[1,2], [3,4]])

>>> print(x)

[[1 2]

[3 4]]

>>> print(x.T)

[[1 3]

[2 4]]

# Note that taking the transpose of a rank 1 array does nothing:

>>> v = np.array([1,2,3])

>>> print(v)

[1 2 3]

>>> print(v.T)

[1 2 3]

```

Numpy还提供了更多操作数组的方法,请查看[Array manipulation routines](https://docs.scipy.org/doc/numpy/reference/routines.array-manipulation.html)

Broadcasting

Broadcasting是一种强有力的机制,它让Numpy可以让不同大小的矩阵在一起进行数学计算。我们常常会有一个小的矩阵和一个大的矩阵,然后我们会需要用小的矩阵对大的矩阵做一些计算。

举个例子,如果我们想要把一个向量加到矩阵的每一行,我们可以这样做:

```

>>> import numpy as np

>>>

>>> x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])

>>> v = np.array([1,0,1])

>>> y = np.empty_like(x) # Create an empty matrix with the same shape as x

>>>

>>> for i in range(4):

y[i,:] = x[i,:] + v

>>> print(y)

[[ 2 2 4]

[ 5 5 7]

[ 8 8 10]

[11 11 13]]

```

这样是行得通的,但是当x矩阵非常大,利用循环来计算就会变得很慢很慢。我们可以换一种思路:

```

>>> import numpy as np

>>> x = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])

>>> v = np.array([1,0,1])

>>> vv = np.tile(v,(4,1))

>>> print(vv)

[[1 0 1]

[1 0 1]

[1 0 1]

[1 0 1]]

>>> y = x + vv

>>> print (y)

[[ 2 2 4]

[ 5 5 7]

[ 8 8 10]

[11 11 13]]

```

Numpy Broadcasting机制可以让我们不用创建vv,就能直接运算,看看下面例子:

```

>>> import numpy as np

>>> x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])

>>> v = np.array([1, 0, 1])

>>> y = x + v

>>> print(y)

[[ 2 2 4]

[ 5 5 7]

[ 8 8 10]

[11 11 13]]

```

对两个数组使用Broadcasting机制要遵守下列规则:

(1)如果数组的秩不同,使用1来将秩较小的数组进行扩展,直到两个数组的尺寸的长度都一样。

(2)如果两个数组在某个维度上的长度是一样的,或者其中一个数组在该维度上长度为1,那么我们就说这两个数组在该维度上是相容的。

(3)如果两个数组在所有维度上都是相容的,他们就能使用Broadcasting。

(4)如果两个输入数组的尺寸不同,那么注意其中较大的那个尺寸。因为Broadcasting之后,两个数组的尺寸将和那个较大的尺寸一样。

(5)在任何一个维度上,如果一个数组的长度为1,另一个数组长度大于1,那么在该维度上,就好像是对第一个数组进行了复制。

如果上述解释看不明白,可以读一读[文档](https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)和这个[解释](http://scipy.github.io/old-wiki/pages/EricsBroadcastingDoc)。

支持Broadcasting机制的函数是全局函数。哪些是全局函数可以在[文档](https://docs.scipy.org/doc/numpy/reference/ufuncs.html#available-ufuncs)中查找。

下面是一些Broadcasting机制的使用:

```

>>> import numpy as np

>>> v = np.array([1,2,3])

>>> w = np.array([4,5])

>>> print(np.reshape(v,(3,1)))

[[1]

[2]

[3]]

>>> print(np.reshape(v,(3,1)) * w)

[[ 4 5]

[ 8 10]

[12 15]]

>>> x = np.array([[1,2,3], [4,5,6]])

>>> print(x + v)

[[2 4 6]

[5 7 9]]

>>> print((x.T + w).T)

[[ 5 6 7]

[ 9 10 11]]

>>> print(x + np.reshape(w, (2, 1)))

[[ 5 6 7]

[ 9 10 11]]

>>> print(x * 2)

[[ 2 4 6]

[ 8 10 12]]

```

Broadcasting机制能够让你的代码更简洁更迅速,能够用的时候请尽量使用!

最近发表
标签列表