前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Hello NumPy》系列-广播操作就看这一篇

《Hello NumPy》系列-广播操作就看这一篇

原创
作者头像
小一不二三
修改2020-02-26 15:09:02
5620
修改2020-02-26 15:09:02
举报

2020,努力做一个无可替代的人!

写在前面的话

没想到吧,NumPy 还有一小节,请珍惜 NumPy 最后的美好时光。

这一节的内容源自于一个朋友的提问,我在交流群里也分享过,具体问题会在正文中复现,知道你们好奇,往下看就好。

害,差点忘了,先回顾下前三节的内容,同学们自行复习:

听说抬起头看天眼眶才不会湿?

我想试试

正文

先来复现一下朋友当时问我的问题:

有一个数据a(DataFrame类型、3行4列的数据),数据b(Series类型、0,1,2),比较a和b后输出布尔型数组

看一下代码演示

代码语言:txt
复制
# 创建 DataFrame 
import pandas as pd
df_a = pd.DataFrame(np.arange(12).reshape(3, 4))
# 输出
   0  1   2   3
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11

# 创建 Series
import numpy as np
series_b = pd.Series(np.arange(3))
# 输出 
0    0
1    1
2    2
dtype: int32

就这样两个数据类型,我刚开始一听第一反应是:这咋比较?数据类型都不一样,维度也不一样。

直到我翻开书看了一下才想起这个概念:广播

先看一下比较的结果是什么

代码语言:txt
复制
df_a > series_b
# 输出
      0      1      2      3
0  False  False  False  False
1   True   True   True  False
2   True   True   True  False

如果你知道为什么会出现上面这个结果,那恭喜你,这一小节你可以直接跳过,相信我,你是最NB的

不知道的同学我们还是要继续的,看完今天的文章想必你会明白。

广播

上面问题提到的一个概念,也是今天唯一的一个知识点:广播

广播指的是不同形状的数组之间的算术运算的执行方式。

首先,将标量数组和数组合并时就会发生简单的广播。

代码语言:txt
复制
# 创建数组
data_arr1 = np.arange(5)

# 输出
[0 1 2 3 4]

data_arr1 * 5
# 输出
[ 0  5 10 15 20]

在上面的乘法运算中,标量值4你也可以看做是一个一行一列的数组,被广播到其他所有的元素上。

这是最简单的标量的广播,那如果是数组的广播呢?

看例子:

代码语言:txt
复制
# 创建4行3列的二维数组
data_arr2 = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3]])
# 输出
[[0 0 0]
 [1 1 1]
 [2 2 2]
 [3 3 3]]

# 创建一维数组
data_arr3 = np.array([1, 2, 3])
# 输出
[1 2 3]

# A + B
data_arr2 + data_arr3
# 输出
[[1 2 3]
 [2 3 4]
 [3 4 5]
 [4 5 6]]

没想到吧,竟然可以计算而没有报错。

这是因为数组 data_arr3 在0轴上做的广播(灰色数字),将原本1行3列的数组广播成4行3列,从而可以与 data_arr2 进行计算

文章首发:公众号『知秋小梦』
文章首发:公众号『知秋小梦』

ok,想必你应该清楚广播是什么作用了吧

当然,广播也不是说所有情况都会广播,人家也是有原则的。

何为广播?

如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1 的维度上进行。

这句话是理解广播的核心,老实说,看懂了吗?

不懂往下看,抬起头看天是看不到答案的,只会不让眼泪流下来!

广播主要发生在三种情况下:

  • 一种是两个数组的维度不相等,但是它们的后缘维度的轴长相符
  • 另一种是两个数组的维度相同,对应维度的轴长要么相等要么任意一个为1
  • 上面两种的结合体
第一种情况

两个数组的维度不相等,但是它们的后缘维度的轴长相符

以上面的例子为例

代码语言:txt
复制
# 输出数组形状/维度
data_arr2.shape
data_arr3.shape

# 输出
(4, 3)
(3,)

可以看到,data_arr2 (4, 3)是二维的,data_arr3 (3,)是一维的,两个数组的维度不相等。同时,它们的后缘维度都是3,后缘维度的轴长相等。

完美符合我们的第一种情况,所以可以进行相加运算。

同样的道理,多维数组也遵循广播原则。

举个图例:

文章首发:公众号『知秋小梦』
文章首发:公众号『知秋小梦』

以此类推:

  • (2,4,2,4) 和 (2,3,4) 是兼容的
  • (2,4,2,4) 和 (2,4) 是兼容的
  • (2,4,2,4) 和 (4) 是兼容的

只是它们需要扩展的轴个数不同。

第二种情况

两个数组的维度相同,对应维度的轴长要么相等要么任意一个为1

这个就比较容易理解了,两个维度相同的数组,对应的维度长度有两种情况:

要么长度相同,要么有一个长度为1

代码语言:txt
复制
# 创建4行1列的二维数组
data_arr4 = np.array([[1, 2, 3, 4]]).reshape(4, 1)
# 输出
[[1]
 [2]
 [3]
 [4]]

# 创建1行3列的二维数组
data_arr5 = np.array([[1, 2, 3]])
# 输出
[[1 2 3]]

这两个数组都是二维数组分别是(4, 1)、(1, 3)

与我们的 data_arr2 (4, 3) 相比,根据第二种情况:

(4, 3) 与 (4, 1) 维度相同,第一维长度相同,第二维存在长度为1;

(4, 3) 与 (1, 3) 维度相同,第一维存在长度为1,第二维长度相同;

(4, 1) 与 (1, 3) 维度相同,第一维存在长度为1,第二维存在长度为1。

所以,以上三个数组之间互相兼容。

稍微画个图例:

文章首发:公众号『知秋小梦』
文章首发:公众号『知秋小梦』

这个时候,第二个二维数组会在1轴上进行广播(灰色数字)

第三种情况

明白了第一种和第二种形式的广播,第三种就是两者的结合体。

举几个简单的例子你就明白了:

(4, 2, 5) 和 (1, 5) 是兼容的。但是不满足第一、第二种情况

(4, 2, 5) 和 (2, 1) 是兼容的。同样不满足第一、第二种情况 看完这三种情况,是不是清楚了一些?

再来细品一下广播的定义

如果两个数组的后缘维度的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的

所以,当我们拿到两个数组,需要判断是否兼容时,先从后缘维度开始,依次往前。

要么对应维度的长度相等,要么对应维度存在某一方的长度为1。

若两个数组的每一个维度都符合这个要求,那这两个数组一定是兼容的。

总结一下:

今天主要讲到一个概念:广播。

正文最后的总结我觉得很到位了,不妨多读几遍理解一下。

看到广播概念的时候,我猜大部分人刚开始也会很懵逼,字都认识,说了个啥?

所以我列举了三种情况去分解这个概念,还记得是哪三种吗?

  • 两个数组的维度不相等,但是它们的后缘维度的轴长相符
  • 两个数组的维度相同,对应维度的轴长要么相等要么任意一个为1
  • 上面两种的结合体

看完这三种情况后,我们回过头再来看概念,是不是就清晰多了?

ok,《Hello NumPy》 系列就完结了,一共四小节,希望对你们有用!

写在后面的话

静下心来写技术文真的也太舒服了吧,希望你们也能静下心舒服的看文章。

我一直以为这几天做的最认真的事就是洗手,结果发现我写文章也可以这么认真。

最近不能去外面吃好的,下班一有空就窝家里写文章,都饿瘦了。

之前买的一箱泡面差不多都吃完了,和我爸妈视频的时候他们都说我饿瘦了

不说了,眼眶全湿了...

下个系列见

原创不易,欢迎点赞噢

文章首发:公众号【知秋小梦】

文章同步:掘金,简书

原文链接:《Hello NumPy》系列-广播操作就看这一篇

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面的话
  • 正文
    • 广播
      • 何为广播?
        • 第一种情况
          • 第二种情况
            • 第三种情况
            • 总结一下:
            • 写在后面的话
              • 原创不易,欢迎点赞噢
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档