盘一盘 Python 系列 2 - NumPy (下)(四)

简介: 盘一盘 Python 系列 2 - NumPy (下)(四)

本文首发于“生信补给站”公众号 https://mp.weixin.qq.com/s/0-9zUTxZC6qefyjLyw1SSA



一维数组



分析结果:


  • 1, 2, 3 的总和是 6
  • 轴 0(只有一个轴) 上的元素求和是 6


用代码验证一下:




arr = np.array([1,2,3])print( 'The total sum is', arr.sum() )print( 'The sum on axis0 is', arr.sum(axis=0) )
The total sum is 6
The sum on axis0 is 6


求和一维数组没什么难度,而且也看不出如果「按轴求和」的规律。下面看看二维数组。



二维数组


image.png


分析结果:


  • 1 到 6 的总和是 6
  • 轴 0 上的元素 (被一个红方括号[]包住的) 是[1, 2, 3][4, 5, 6],求和得到[[5, 6, 7]]
  • 轴 1 上的元素 (被两个蓝方括号[] 包住的) 分别是 1, 2, 3 和 4, 5, 6,求和得到 [[1+2+3, 4+5+6]]=[[6, 15]]


用代码验证一下:



arr = np.arange(1,7).reshape((2,3))print( arr )
[[1 2 3]
 [4 5 6]]



print( 'The total sum is', arr.sum() )print( 'The sum on axis0 is', arr.sum(axis=0) )print( 'The sum on axis1 is', arr.sum(axis=1) )
The total sum is 21
The sum on axis0 is [5 7 9]
The sum on axis1 is [ 6 15]


结果是对的,但是好像括号比上图推导出来的少一个。原因np.sum()里面有个参数是 keepdims,意思是「保留维度」,默认值时 False,因此会去除多余的括号,比如 [[5, 7, 9]] 会变成 [5, 7, 9]。


如果把 keepdims 设置为 True,那么打印出来的结果和上图推导的一模一样。



print( arr.sum(axis=0, keepdims=True) )print( arr.sum(axis=1, keepdims=True) )
[[5 7 9]]
[[ 6]
[15]]



三维数组



分析结果:


  • 1 到 12 的总和是 78
  • 轴 0 上的元素是一个红方括号[] 包住的两个[[ ]],对其求和得到一个[ [[ ]] ]
  • 轴 1 上的元素是两个蓝方括号[] 包住的两个[ ],对其求和得到两个[[ ]],即 [ [[ ]],[[ ]]]
  • 轴 2 上的元素是四个绿方括号[] 包住的三个标量,对其求和得到四个[],即 [ [[ ],[ ]], [[ ],[ ]] ]


用代码验证一下:



arr = np.arange(1,13).reshape((2,2,3))print(arr)
[[[ 1 2 3]
  [ 4 5 6]]
 [[ 7 8 9]
  [10 11 12]]]


print( 'The total sum is', arr.sum() )print( 'The sum on axis0 is', arr.sum(axis=0) )print( 'The sum on axis1 is', arr.sum(axis=1) )print( 'The sum on axis2 is', arr.sum(axis=2) )
The total sum is 78
The sum on axis0 is [[ 8 10 12] [14 16 18]]
The sum on axis1 is [[ 5 7 9] [17 19 21]]
The sum on axis2 is [[ 6 15] [24 33]]


打印出来的结果比上图推导结果少一个括号,也是因为 keepdims 默认为 False。


四维数组



不解释了,彩色括号画的人要抓狂了。通用规律:当在某根轴上求和,明晰该轴的元素,再求和。具体说来:


  • 轴 0上求和,包含是两个[],对其求和
  • 轴 1 上求和,包含是两个 [],对其求和
  • 轴 2 上求和,包含是两个 [],对其求和
  • 轴 3 上求和,包含是三个标量,对其求和


用代码验证一下:


arr = np.arange(1,25).reshape((2,2,2,3))print(arr)
[[[[ 1 2 3]
   [ 4 5 6]]
  [[ 7 8 9]
   [10 11 12]]]
 [[[13 14 15]
   [16 17 18]]
  [[19 20 21]
   [22 23 24]]]]


print( 'The total sum is', arr.sum() )print( 'The sum on axis0 is', arr.sum(axis=0) )print( 'The sum on axis1 is', arr.sum(axis=1) )print( 'The sum on axis2 is', arr.sum(axis=2) )print( 'The sum on axis3 is', arr.sum(axis=3) )
The total sum is 300
The sum on axis0 is [[[14 16 18] [20 22 24]]
                     [[26 28 30] [32 34 36]]]
The sum on axis1 is [[[ 8 10 12] [14 16 18]]
                     [[32 34 36] [38 40 42]]]
The sum on axis2 is [[[ 5 7 9] [17 19 21]]
                     [[29 31 33] [41 43 45]]]
The sum on axis3 is [[[ 6 15] [24 33]]
                     [[42 51] [60 69]]]


打印出来的结果比上图推导结果少一个括号,也是因为 keepdims 默认为 False。


小节

除了 sum 函数,整合函数还包括 min, max, mean, std cumsum,分别是求最小值、最大值、均值、标准差和累加,这些函数对数组里的元素整合方式和 sum 函数相同,就不多讲了。总结来说我们可以对数组


  • 所有的元素整合
  • 在某个轴 (axis) 上的元素整合


整合函数= {sum, min, max, mean, std,cumsum}


5.4 广播机制计算



当对两个形状不同的数组按元素操作时,可能会触发「广播机制」。具体做法,先适当复制元素使得这两个数组形状相同后再按元素操作,两个步骤:


  1. 广播轴 (broadcast axis):比对两个数组的维度,将形状小的数组的维度 (轴) 补齐
  2. 复制元素:顺着补齐的轴,将形状小的数组里的元素复制,使得最终形状和另一个数组吻合


在给出「广播机制」需要的严谨规则之前,我们先来看看几个简单例子。


例一:标量和一维数组


arr = np.arange(5)print( arr )print( arr + 2 )
[0 1 2 3 4]
[2 3 4 5 6]


元素 2 被广播到数组 arr 的所有元素上。


例二:一维数组和二维数组


arr = np.arange(12).reshape((4,3))print( arr )print( arr.mean(axis=0) )print( arr - arr.mean(axis=0) )
[[ 0 1 2]
 [ 3 4 5]
 [ 6 7 8]
 [ 9 10 11]]
[4.5 5.5 6.5]
[[-4.5 -4.5 -4.5]
 [-1.5 -1.5 -1.5]
 [ 1.5 1.5 1.5]
 [ 4.5 4.5 4.5]]


沿轴 0 的均值的一维数组被广播到数组 arr 的所有的行上。



现在我们来看看「广播机制」的规则:


广播机制的规则


知识点

当我们对两个数组操作时,如果它们的形状


  • 不相容 (incompatible),广播机制不能进行
  • 相容 (compatible),广播机制可以进行


因此,进行广播机制分两步


  1. 检查两个数组形状是否兼容,即从两个形状元组最后一个元素,来检查

    1. 它们是否相等
    2. 是否有一个等于 1

  2. 一旦它们形状兼容,确定两个数组的最终形状。



例三:维度一样,形状不一样

用个例子来应用以上广播机制规则


a = np.array([[1,2,3]])b = np.array([[4],[5],[6]])print( 'The shape of a is', a.shape )print( 'The shape of b is', b.shape )
The shape of a is (1, 3)
The shape of b is (3, 1)


回顾进行广播机制的两步


  1. 检查数组 a 和 b 形状是否兼容,从两个形状元组 (1, 3) 和 (3, 1)最后一个元素开始检查,发现它们都满足『有一个等于 1』的条件。

  2. 因此它们形状兼容,两个数组的最终形状为 (max(1,3), max(3,1)) = (3, 3)


到此,a 和 b 被扩展成 (3, 3) 的数组,让我们看看 a + b 等于多少



c = a + bprint( 'The shape of c is', c.shape )print( 'a is', a )print( 'b is', b )print( 'c = a + b =', c )
The shape of c is (3, 3)
a is [[1 2 3]]
b is [[4]
      [5]
      [6]]
c = a + b = [[5 6 7]
             [6 7 8]
             [7 8 9]]


例四:维度不一样


a = np.arange(5)b = np.array(2)print( 'The dimension of a is', a.ndim, 'and the shape of a is', a.shape )print( 'The dimension of b is', b.ndim, 'and the shape of b is', b.shape )
The dimension of a is 1 and the shape of a is (5,)
The dimension of b is 0 and the shape of b is ()


数组 a 和 b 形状分别为 (5,) 和 (),首先我们把缺失的维度用 1 补齐得到 (5,) 和 (1,),再根据广播机制那套流程得到这两个形状是兼容的,而且最终形状为 (5,)。


用代码来看看 a + b 等于多少



c = a + bprint( 'The dimension of c is', c.ndim, 'and the shape of c is', c.shape, '\n' )print( 'a is', a )print( 'b is', b )print( 'c = a + b =', c )
The dimension of c is 1 and the shape of c is (5,)
a is [0 1 2 3 4]
b is 2
c = a + b = [2 3 4 5 6]




现在对广播机制有概念了吧,来趁热打铁搞清楚下面这五个例子,你就完全弄懂它了。



a = np.array( [[[1,2,3], [4,5,6]]] )b1 = np.array( [[1,1,1], [2,2,2], [3,3,3]] )b2 = np.arange(3).reshape((1,3))b3 = np.arange(6).reshape((2,3))b4 = np.arange(12).reshape((2,2,3))b5 = np.arange(6).reshape((2,1,3))print( 'The dimension of a is', a.ndim, 'and the shape of a is', a.shape )print( 'The dimension of b1 is', b.ndim, 'and the shape of b1 is', b1.shape, '\n')print( 'The dimension of a is', a.ndim, 'and the shape of a is', a.shape )print( 'The dimension of b2 is', b.ndim, 'and the shape of b2 is', b2.shape, '\n' )print( 'The dimension of a is', a.ndim, 'and the shape of a is', a.shape )print( 'The dimension of b3 is', b.ndim, 'and the shape of b3 is', b3.shape, '\n' )print( 'The dimension of a is', a.ndim, 'and the shape of a is', a.shape )print( 'The dimension of b4 is', b.ndim, 'and the shape of b4 is', b4.shape, '\n' )print( 'The dimension of a is', a.ndim, 'and the shape of a is', a.shape )print( 'The dimension of b5 is', b.ndim, 'and the shape of b5 is', b5.shape )
The dimension of a is 3 and the shape of a is (1, 2, 3)
The dimension of b1 is 0 and the shape of b1 is (3, 3)
The dimension of a is 3 and the shape of a is (1, 2, 3)
The dimension of b2 is 0 and the shape of b2 is (1, 3)
The dimension of a is 3 and the shape of a is (1, 2, 3)
The dimension of b3 is 0 and the shape of b3 is (2, 3)
The dimension of a is 3 and the shape of a is (1, 2, 3)
The dimension of b4 is 0 and the shape of b4 is (2, 2, 3)
The dimension of a is 3 and the shape of a is (1, 2, 3)
The dimension of b5 is 0 and the shape of b5 is (2, 1, 3)


对于数组 a 和 b1,它们形状是 (1, 2, 3) 和 (3, 3)。元组最后一个都是 3,兼容;倒数第二个是 3 和 2,即不相等,也没有一个是 1,不兼容a 和 b1 不能进行广播机制。不行就看看下面代码:




c1 = a + b1print( c1 )print( c1.shape )
ValueError: operands could not be broadcast
together with shapes (1,2,3) (3,3)


a 和其他 b2, b3, b4, b5 都可以进行广播机制,自己分析吧。



c2 = a + b2print( c2 )print( c2.shape )
[[[1 3 5]
  [4 6 8]]]
(1, 2, 3)



c3 = a + b3print( c3 )print( c3.shape )
[[[ 1 3 5]
  [ 7 9 11]]]
(1, 2, 3)



c4 = a + b4print( c4 )print( c4.shape )
[[[ 1 3 5]
  [ 7 9 11]]
 [[ 7 9 11]
  [13 15 17]]]
(2, 2, 3)



c5 = a + b5print( c5 )print( c5.shape )
[[[ 1 3 5]
  [ 4 6 8]]
 [[ 4 6 8]
  [ 7 9 11]]]
(2, 2, 3)


6总结



NumPy 篇终于完结!即上贴讨论过的数组创建、数组存载和数组获取,本贴讨论了数组变形、数组计算


数组变形有以下重要操作:


  • 改变维度的重塑打平
  • 改变分合的合并分裂
  • 复制本质的重复拼接
  • 其他排序插入删除复制


数组计算有以下重要操作:


  1. 元素层面:四则运算、函数,比较
  2. 线性代数:务必弄懂点乘函数 dot()
  3. 元素整合:务必弄懂轴这个概念!
  4. 广播机制:太重要了,神经网络无处不在!


下篇讨论用于科学计算的 SciPy。Stay Tuned!

相关文章
|
10天前
|
机器学习/深度学习 数据采集 数据挖掘
解锁 Python 数据分析新境界:Pandas 与 NumPy 高级技巧深度剖析
Pandas 和 NumPy 是 Python 中不可或缺的数据处理和分析工具。本文通过实际案例深入剖析了 Pandas 的数据清洗、NumPy 的数组运算、结合两者进行数据分析和特征工程,以及 Pandas 的时间序列处理功能。这些高级技巧能够帮助我们更高效、准确地处理和分析数据,为决策提供支持。
25 2
|
16天前
|
存储 数据处理 Python
Python科学计算:NumPy与SciPy的高效数据处理与分析
【10月更文挑战第27天】在科学计算和数据分析领域,Python凭借简洁的语法和强大的库支持广受欢迎。NumPy和SciPy作为Python科学计算的两大基石,提供了高效的数据处理和分析工具。NumPy的核心功能是N维数组对象(ndarray),支持高效的大型数据集操作;SciPy则在此基础上提供了线性代数、信号处理、优化和统计分析等多种科学计算工具。结合使用NumPy和SciPy,可以显著提升数据处理和分析的效率,使Python成为科学计算和数据分析的首选语言。
26 3
|
18天前
|
数据采集 数据可视化 数据处理
如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`)
本文介绍了如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`),加载历史数据,计算均线和其他技术指标,实现交易逻辑,记录和可视化交易结果。示例代码展示了如何根据均线交叉和价格条件进行开仓、止损和止盈操作。实际应用时需注意数据质量、交易成本和风险管理。
38 5
|
17天前
|
存储 机器学习/深度学习 算法
Python科学计算:NumPy与SciPy的高效数据处理与分析
【10月更文挑战第26天】NumPy和SciPy是Python科学计算领域的两大核心库。NumPy提供高效的多维数组对象和丰富的数学函数,而SciPy则在此基础上提供了更多高级的科学计算功能,如数值积分、优化和统计等。两者结合使Python在科学计算中具有极高的效率和广泛的应用。
33 2
|
1月前
|
机器学习/深度学习 数据采集 算法
探索Python科学计算的边界:NumPy、Pandas与SciPy在大规模数据分析中的高级应用
【10月更文挑战第5天】随着数据科学和机器学习领域的快速发展,处理大规模数据集的能力变得至关重要。Python凭借其强大的生态系统,尤其是NumPy、Pandas和SciPy等库的支持,在这个领域占据了重要地位。本文将深入探讨这些库如何帮助科学家和工程师高效地进行数据分析,并通过实际案例来展示它们的一些高级应用。
49 0
探索Python科学计算的边界:NumPy、Pandas与SciPy在大规模数据分析中的高级应用
|
1月前
|
机器学习/深度学习 算法 数据挖掘
【Python篇】深度探索NumPy(下篇):从科学计算到机器学习的高效实战技巧1
【Python篇】深度探索NumPy(下篇):从科学计算到机器学习的高效实战技巧
50 5
|
1月前
|
机器学习/深度学习 算法 数据可视化
【Python篇】深度探索NumPy(下篇):从科学计算到机器学习的高效实战技巧2
【Python篇】深度探索NumPy(下篇):从科学计算到机器学习的高效实战技巧
39 1
|
1月前
|
数据挖掘 索引 Python
Python数据分析篇--NumPy--进阶
Python数据分析篇--NumPy--进阶
16 0
|
1月前
|
数据挖掘 索引 Python
Python数据分析篇--NumPy--入门
Python数据分析篇--NumPy--入门
33 0
|
2月前
|
机器学习/深度学习 数据处理 Python
从NumPy到Pandas:轻松转换Python数值库与数据处理利器
从NumPy到Pandas:轻松转换Python数值库与数据处理利器
75 0