一、数组的广播机制

1、先来看几个例子

a = np.array([1,3,2,5])
display(a.shape)

b = np.array([4])
display(b.shape)

c = np.arange(1,13).reshape(3,4)
display(c)
display(c.shape)

结果如下:

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_broadcast

2、numpy官网关于广播机制的一句原话

for both arrays 
in an operation must either be the same size or one of them must be one.

"翻译如下"
为了更够广播,进行操作的两个数组的尾部维度必须相同,或者其中一个数组的尾部维度是1。
这个你可能会很蒙,毕竟是英译过来的,说不定还没有翻译到作者所写的那层意思,因此你简
单了解一下这个就行。下面我们会对广播的使用做更为详细的总结!!!
1)什么是广播机制?
  • 概念:广播(Broadcast)是numpy对不同形状(shape)的数组,进行数值计算的方式,对数组的算术运算通常在相对应的元素上进行。
  • 注意:不同形状的数组元素之间进行数值计算,会触发广播机制;同种形状的数组元素之间,直接是对应元素之间进行数值计算。
2)数组与标量之间的运算

① 创建三个不同维度的数组

a = 2
display(a)

b = np.array([1,2])
display(b)

c = np.arange(1,7).reshape(3,2)
display(c)

c1 = np.arange(1,5).reshape(2,2)
display(c1)

d = np.arange(1,9).reshape(2,2,2)
display(d)

结果如下:

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_python_02


② 标量和一维、二维、三维数组之间的广播运算

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_numpy_03


③ 一维数组和二维数组之间的广播运算

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_数组_04


⑤ 二维数组和三维数组元素之间的广播运算

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_broadcast_05

3)图示说明:什么样的数据才可以启用广播机制?

① 首先,我们分别构造了几个数组;

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_broadcast_06


注意:对于一个标量来说,我们可以将这一个数字的形状看成是一行一列;对于一个一维数组,我们可以将它的形状看成是一行多列;② 广播机制的详细图解

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_numpy数组广播机制_07


结论:

  • 不同形状的数组之间能不能触发广播机制,主要看对应形状的每一个位置上的数字,是否满足如下要求。
  • ① 要么对应位置上的数字完全一致,可以触发广播机制,比如说第Ⅵ组;
  • ② 对应位置上的数字要是不一样,那么对应位置上,必须有一个数字是1,比如说Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ;
  • 如果对应位置上的数字不仅不相同,且没有任何一个的数字为1,那么就不能使用广播机制,比如说Ⅶ。

二、数组元素的底层存储与存储顺序说明

1、构造一个二维数组,以二维数组进行说明(二维数组用的多一些)

x = np.arange(1,13).reshape(3,4)
display(x)

结果如下:

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_broadcast_08


结果分析:

  • 当我们什么都不指定,直接创建了一个数组后,数据默认的填充方式是,先填满每一行,然后再填充第二行,依次进行下去。
  • 原因是:numpy的底层是集成了C语言的,因此numpy数组元素的底层存储也就是“C风格”的,下面我们来对这种风格进行说明。

2、C语言风格和F语言风格

1)不同风格的数组元素的底层存储

  以二维数组来说,不管是C语言风格,还是F语言风格,他们在底层的存储顺序都是一行的,只不过最终呈现的效果属于“虚拟展示”。这里我先拿出来说明一下,让大家有一个主观印象,下面我们用两张图展示一下。

① C语言风格

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_numpy数组广播机制_09


② F语言风格

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_numpy_10

2)什么是C语言风格和F语言风格?

  C指的就是C语言,numpy底层集成了C语言,因此当你不指定order参数的时候,默认就采用的是C语言风格,C语言风格,最右边的索引变化最快。

  F指的就是F语言,最左边的索引变化最快。

① 一张图形象说明上述文字;

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_numpy_11


图示说明:

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_python_12

3、案例讲解

1)创建一个数组,分别使用不同的语言风格进行元素填充;

① 指定order=“C”(默认就是order=“C”)

a = np.arange(1,13)
b = a.reshape(3,4,order="C")
display(b)

结果如下:

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_python_13


结果分析:

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_numpy_14


② 指定order=“F”

a = np.arange(1,13)
b = a.reshape(3,4,order="F")
display(b)

结果如下:

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_numpy_15


结果分析:

numpy的使用说明(五):数组的广播机制、数组元素的底层存储_数组_16