继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

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

小一的学习笔记
关注TA
已关注
手记 9
粉丝 2
获赞 16

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

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



写在前面的话

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

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

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


正文

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

先来看一下四则运算:

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

# 创建 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,数组创建完毕,试着进行计算

# 数组加法运算
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]]

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

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

看例子:

# 数组与标量的算术运算
data_arr1 * 5
# 输出
[[ 0  5 10]
 [15 20 25]]

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

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

再来看下矩阵运算

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

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

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

data_arr1
# 输出
[[0 1 2]
 [3 4 5]]

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

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

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

# 创建数组
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)

# 创建数组
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,如何进行条件逻辑表述呢?

# 创建数组
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 中选取。

先来看一下列表推导式:

# 实现三元表达式功能
result = [(x if tag else y) 
			for x, y, tag in zip(data_xarr, data_yarr, data_tag)
		 ]

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

是不是很麻烦?

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

# 使用 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

# 创建 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的值呢?

# 保留小于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的数的和、平均值、标准差方差等

# 创建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 方法进行排序

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 用于找出数组中的唯一值并返回已排序的结果

# `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 系列在我的计划中还有最后一篇,今天是第三篇。

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

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

碎碎念一下

最全的干货已经开始了,大家不要掉队啊。

建议大家关注我,不要错过高阶部分内容!!!


原创不易,欢迎点赞噢

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

文章同步:掘金,简书


打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP