前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Hello NumPy》系列-运算与函数应用

《Hello NumPy》系列-运算与函数应用

原创
作者头像
小一不二三
修改2020-02-20 14:39:45
7640
修改2020-02-20 14:39:45
举报
文章首发:公众号『知秋小梦』
文章首发:公众号『知秋小梦』

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

写在前面的话

NumPy 第三小节,同学们自行复习第一二小节:

疫情严峻,有空多学习,没事多看看文章,期待阳春三月!

高阶部分篇篇都是干货,建议大家不要错过任何一节内容,最好关注我,方便看到每次的文章推送。

正文

前面在创建 NumPy 数组的时候,通过创建方法可以发现有些类似于线性代数,比如创建的正态分布数组、对角数组等,也确实是这样,矩阵的一些特性 NumPy 同样具有。

先来看一下四则运算:

创建维度相同的两个数组,数组1的值分别为0-5,数组2是一个全1数组

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

# 创建 2行3列的全1数组
data_ones = np.ones((2, 3), dtype=np.int)
# 输出
[[1 1 1]
 [1 1 1]]

ok,数组创建完毕,试着进行计算

代码语言:txt
复制
# 数组加法运算
data_arr1 + data_ones
# 输出
[[1 2 3]
 [4 5 6]]
 
# 数组除法运算
data_ones / (data_arr1 + data_ones)
# 输出
[[1.         0.5        0.33333333]
 [0.25       0.2        0.16666667]]

和我们实际进行数组计算的一致,数组之间的任何算术运算都会应用到元素级。

但是,这个前提是两个数组的维度一致,如果,不一致?或者是个数呢?

看例子:

代码语言:txt
复制
# 数组与标量的算术运算
data_arr1 * 5
# 输出
[[ 0  5 10]
 [15 20 25]]

同样,数组与标量的算术运算也会将标量的值传播到各个元素。

不同大小数组之间的运算叫做广播。暂且不解释,我们下节专门说它。

再来看下矩阵运算

在线性代数中,有矩阵转置,在 NumPy 中,也就有了数组转置。

转置(transpose)是一种数组维度重塑的一种特殊形式,它返回的是源数据的视图。

数组不仅有 transpose 方法,还有一个特殊的 T 属性。

代码语言:txt
复制
data_arr1
# 输出
[[0 1 2]
 [3 4 5]]

# 转置操作的两种实现方法
data_arr1.T
data_arr1.transpose()
# 输出
[[0 3]
 [1 4]
 [2 5]]

在进行矩阵运算时,比如我们需要计算矩阵内积:X^TX,可以使用 np.dot 计算

根据公式:矩阵内积 = X 的转置乘以 X

代码语言:txt
复制
# 创建数组
data_arr2 = np.random.randn(1,3)
# 输出
[[-0.14205835 -1.43319166  0.8389062 ]]

# 计算矩阵内积
np.dot(data_arr2.T, data_arr2)
# 输出
[[ 0.02018058  0.20359685 -0.11917363]
 [ 0.20359685  2.05403832 -1.20231337]
 [-0.11917363 -1.20231337  0.70376361]]

还有高维数组的转置这些,实际上并不常用,而且也不是很好理解,就不再提了,最常用的就是二维数组的转置,会这个就可。

列举部分线性代数在 NumPy 的实现

函数

说明

dot

矩阵乘法

trace

计算对角线元素的和

det

计算矩阵行列式

inv

计算方阵的逆

solve

解线性方程组 Ax = b,其中 A 为一个方阵

lstsq

计算 Ax = b 的最小二乘解

......

......

通用函数

通用函数(即 ufunc)是一种对 ndarray 中的数据执行元素级运算的函数。

你可以将其看做简单函数的矢量化包装器:接受一个或多个标量值,并产生一个或多个标量值。

先来看看一元通用函数(unary ufunc)

代码语言:txt
复制
# 创建数组
data_unary = np.arange(10)
# 输出
[0 1 2 3 4 5 6 7 8 9]

# 求数组每个元素的平方根
np.sqrt(data_unary)
# 输出
[0.         1.         1.41421356 1.73205081 2.         2.23606798
 2.44948974 2.64575131 2.82842712 3.        ]

# 求数组的最大最小值
np.min(data_unary)
np.max(data_unary)
# 输出
0
9

就和 Python 的常规语法一样,NumPy 通用函数也是直接调用即可。

另外还有一些接受2个数组,返回一个结果数组的通用函数(二元函数)

列举一些常用的一元和二元函数

函数

说明

一元函数

abs

计算整数、浮点数或负数的绝对值。

一元函数

sqrt

计算个元素的平方根

一元函数

square

计算各元素的平凡

一元函数

exp

计算各元素的指数

一元函数

log、log10、log2

分别为底数为e的log、底数为10的log、底数为2的log

一元函数

sign

计算各元素的正负号

一元函数

ceil

计算各元素的ceiling值(大于等于该值的最小整数)

一元函数

floor

计算各元素的floor值(小于等于该值的最大整数)

一元函数

cos、cosh、sin、sinh、tan、tanh

普通和双曲线三角函数

一元函数

isnan

返回一个数组表示”哪些是NaN“的布尔型数组

......

......

......

二元函数

add

将数组中对应的元素相加

二元函数

sutract

从第一个数组中减去第二个数组中的元素

二元函数

multiply

数组元素相乘

二元函数

divide

数组元素相除

二元函数

power

计算 A 的 B 次方

......

......

......

是不是以为到这就结束了?

没错,快结束了,但是我总觉得下面的内容才是今天的重点内容,信不信由你。

条件逻辑表述

我们都知道 Python 中的三元表达式: x if condition else y

那如果我们有两个值数组分别表示 x 和 y,有一个布尔数组表示 condition,如何进行条件逻辑表述呢?

代码语言:txt
复制
# 创建数组
data_xarr = np.array([1, 2, 3, 4, 5])
data_yarr = np.array([-1, -2, -3, -4, -5])
data_tag = np.array([True, False, False, False, True])

根据布尔数组 data_tag 选取 data_xarr 和 data_yarr 的值:当 data_tag 为 True,选择 data_xarr 的值,否则从 data_yarr 中选取。

先来看一下列表推导式:

代码语言:txt
复制
# 实现三元表达式功能
result = [(x if tag else y) 
			for x, y, tag in zip(data_xarr, data_yarr, data_tag)
		 ]

# 输出
[1, -2, -3, -4, 5]

是不是很麻烦?

NumPy 中一个函数就可以实现上面的功能!!!

代码语言:txt
复制
# 使用 where 函数实现三元表达式功能
result = np.where(data_tag, data_xarr, data_yarr)

# 输出
[ 1 -2 -3 -4  5]

是不是很方便?

解释一下 where 函数的用法:第一个参数是条件 condition,第二和第三个参数相当于三元表达式中的 x 和 y。其中 x 和 y 不必是数组,也可以是标量值, where 函数返回一个新的数组。

例如,通过 where 函数进行数据清洗,大于0的数全部置为1,小于0的数全部置为-1

代码语言:txt
复制
# 创建 3*3 的数组
data_warr = np.random.randn(3, 3)
# 输出
[[-0.57519374  0.91571952  0.2104197 ]
 [ 0.32693672  0.95512399 -0.09581747]
 [-1.40553911 -0.96782964  0.73291699]]

# 大于0的数全部置为1,小于0的数全部置为-1
result = np.where(data_warr>0, 1, -1)
# 输出
[[-1  1  1]
 [ 1  1 -1]
 [-1 -1  1]]

如果要保留小于0的数组值,只替换大于0的值呢?

代码语言:txt
复制
# 保留小于0的数组值,只替换大于0的值
np.where(data_warr>0, 1, data_warr)
# 输出
[[-0.57519374  1.          1.        ]
 [ 1.          1.         -0.09581747]
 [-1.40553911 -0.96782964  1.        ]]
比 where 更重要的内容

布尔判断+统计,你没听错,数据分析常用噢

举例:随机数中所有大于0的数的和、平均值、标准差方差等

代码语言:txt
复制
# 创建10个范围在-10~10的随机整数
data_rn = np.random.randint(-10, 10, 10)
# 输出
[-9 -2 -1 -7  9  9 -4  6  3 -1]

# 大于0的所有数的和、平均值、标准差方差
(data_rn>0).sum()
(data_rn>0).mean()
(data_rn>0).std()
(data_rn>0).var()
# 输出
4
0.4
0.48989794855663565
0.24000000000000005

any、how 检测

any 用于测试数组中是否存在一个或多个 True

all 用于检查数组中所有值是否都是 True

sort 排序

和 Python 内置的列表类型一样,NumPy 数组也可以通过 sort 方法进行排序

代码语言:txt
复制
data_sort = np.array([[1, 0, -2, 5, 4], [-1, -3, 3, 4, 2]])
# 输出
[[ 1  0 -2  5  4]
 [-1 -3  3  4  2]]
 
# 默认排序(行)
data_sort.sort()
# 输出
[[-2  0  1  4  5]
 [-3 -1  2  3  4]]

# 在0轴上排序(列)
data_sort.sort(axis=0)
# 输出
[[-3 -1  1  3  4]
 [-2  0  2  4  5]]

unique 唯一化

针对一维数组最常用的基本集合运算:unique 用于找出数组中的唯一值并返回已排序的结果

代码语言:txt
复制
# `unique 找出数组中的唯一值并返回已排序的结果`
data_ints = np.array([2, 3, 1, 1, 2, 4, 6, 7, -1])
np.unique(data_ints)

# 输出
[-1  1  2  3  4  6  7]

呼呼,没骗你吧,这才是最实用的内容。

总结一下:

说实话,今天的内容挺多的。

总结一下:

  • NumPy 数组的四则运算
  • NumPy 数组的矩阵运算
  • 条件逻辑表述 where
  • 布尔判断、统计、排序、唯一化

前两小节属于运算中比较基础的内容,知道是什么、怎么用就可以了。

重点是后面两小节,在实际项目中用处很大,建议大家看着例子多读几篇。

可以的话,在自己电脑上运行一遍试试

写在后面的话

透个底,NumPy 系列在我的计划中还有最后一篇,今天是第三篇。

不知道大家学的怎么样,有的内容了解就行,也没必要死磕下去。

当然,我标重点还是建议都掌握啦,下期见!

碎碎念一下

最全的干货已经开始了,大家不要掉队啊。 建议大家关注我,不要错过高阶部分内容!!!

原创不易,欢迎点赞噢

文章首发:公众号【知秋小梦】 文章同步:掘金,简书

原文链接:《Hello NumPy》系列-运算与函数应用

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面的话
  • 正文
    • 先来看一下四则运算:
      • 再来看下矩阵运算
        • 通用函数
          • 条件逻辑表述
            • 比 where 更重要的内容
            • 总结一下:
            • 写在后面的话
              • 碎碎念一下
                • 原创不易,欢迎点赞噢
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档