盘一盘 Python 系列 2 - NumPy (上)(三 )

简介: 盘一盘 Python 系列 2 - NumPy (上)(三 )

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

3数组的获取


获取数组是通过索引 (indexing) 和切片 (slicing) 来完成的,


  • 切片是获取一段特定位置的元素
  • 索引是获取一个特定位置的元素


索引和切片的方式和列表一模一样,参考 Python 入门篇 (上)的 2.3 节。对于一维数组 arr,


  • 切片写法是 arr[start : stop : step]
  • 索引写法是 arr[index]


因此,切片的操作是可以用索引操作来实现的 (一个一个总能凑成一段),只是没必要罢了。为了简化,我们在本章三节标题里把切片和索引都叫做索引。


索引数组有三种形式,正规索引 (normal indexing)、布尔索引 (boolean indexing) 和花式索引 (fancy indexing)。


3.1 正规索引



虽然切片操作可以由多次索引操作替代,但两者最大的区别在于


  • 切片得到的是原数组的一个视图 (view) ,修改切片中的内容改变原数组
  • 索引得到的是原数组的一个复制 (copy),修改索引中的内容改变原数组


请看下面一维数组的例子来说明上述两者的不同。


一维数组



arr = np.arange(10)arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])


arr[6]索引第 7 个元素 (记住 Python 是从 0 开始记录位置的)


arr[6]
6


把它赋给变量 a,并重新给 a 赋值 1000,但是元数组 arr 第 7 个元素的值还是 6,并没有改成 1000。




a = arr[6]a = 1000arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])


arr[5:8]切片第 6 到 8 元素 (记住 Python 切片包头不包尾)


arr[5:8]
array([5, 6, 7])


把它赋给变量 b,并重新给 b 的第二个元素赋值 12,再看发现元数组 arr 第 7 个元素的值已经变成 12 了。




b = arr[5:8]b[1] = 12arr
array([ 0, 1, 2, 3, 4, 5, 12, 7, 8, 9])



这就证实了切片得到原数组的视图 (view),更改切片数据会更改原数组,而索引得到原数组的复制 (copy), 更改索引数据不会更改原数组。希望用下面一张图可以明晰 view 和 copy 的关系。



了解完一维数组的切片和索引,类比到二维和多维数组上非常简单。



二维数组



arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])arr2d
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])


索引

情况一:arr2d[2] 来索引第三行,更严格的说法是索引「轴 0」上的第三个元素。


arr2d[2]
array([7, 8, 9])


情况二:arr2d[0][2] 来索引第一行第三列


arr2d[0][2]
3


索引二维数组打了两个中括号好麻烦,索引五维数组不是要打了五个中括号?还有一个简易方法,用 arr2d[0, 2] 也可以索引第一行第三列


arr2d[0,2]
3


切片

情况一:arr2d[:2] 切片前两行,更严格的说法是索引「轴 0」上的前两个元素。


arr2d[:2]
array([[1, 2, 3],
       [4, 5, 6]])


情况二:arr2d[:, [0,2]] 切片第一列和第三列


arr2d[:,[0,2]]
array([[1, 3],
       [4, 6],
       [7, 9]])


情况三:arr2d[1, :2] 切片第二行的前两个元素


arr2d[1, :2]
array([4, 5])


情况四:arr2d[:2, 2] 切片第三列的前两个元素


arr2d[:2, 2]
array([3, 6])



3.2 布尔索引



布尔索引,就是用一个由布尔 (boolean) 类型值组成的数组来选择元素的方法。


假设我们有阿里巴巴 (BABA),脸书 (FB) 和京东 (JD) 的


  • 股票代码 code 数组
  • 股票价格 price 数组:每行记录一天开盘最高收盘价格。







code = np.array(['BABA', 'FB', 'JD', 'BABA', 'JD', 'FB'])price = np.array([[170,177,169],[150,159,153],                  [24,27,26],[165,170,167],                  [22,23,20],[155,116,157]])price
array([[170, 177, 169],
       [150, 159, 153],
       [ 24, 27, 26],
       [165, 170, 167],
       [ 22, 23, 20],
       [155, 161, 157]])


假设我们想找出 BABA 对应的股价,首先找到 code 里面是 'BABA' 对应的索引 (布尔索引),即一个值为 True 和 False 的布尔数组。


code == 'BABA'
array([ True, False, False, True, False, False])


用该索引可以获取 BABA 的股价:


price[ code == 'BABA' ]
array([[170, 177, 169],
       [165, 170, 167]])


用该索引还可以获取 BABA 的最高和收盘价格:


price[ code == 'BABA', 1: ]
array([[177, 169],
       [170, 167]])


再试试获取 JD 和 FB 的股价:


price[ (code == 'FB')|(code == 'JD') ]
array([[150, 159, 153],
       [ 24, 27, 26],
       [ 22, 23, 20],
       [155, 161, 157]])


虽然下面操作没有实际意义,试试把股价小于 25 的清零。



price[ price < 25 ] = 0price
array([[170, 177, 169],
       [150, 159, 153],
       [ 0, 27, 26],
       [165, 170, 167],
       [ 0, 0, 0],
       [155, 161, 157]])


注:这种布尔索引的操作在 Pandas 更常用也更方便,看完 pandas 那帖后就可以忽略这一节了。



3.3 花式索引



花式索引是获取数组中想要的特定元素的有效方法。考虑下面数组:



arr = np.arange(32).reshape(8,4)arr
array([[ 0, 1, 2, 3],
       [ 4, 5, 6, 7],
       [ 8, 9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23],
       [24, 25, 26, 27],
       [28, 29, 30, 31]])


假设你想按特定顺序来获取第 5, 4 和 7 行时,用 arr[ [4,3,6] ]


arr[ [4,3,6] ]
array([[16, 17, 18, 19],
       [12, 13, 14, 15],
       [24, 25, 26, 27]])


假设你想按特定顺序来获取倒数第 4, 3 和 6 行时 (即正数第 4, 5 和 2 行),用 arr[ [-4,-3,-6] ]


arr[ [-4,-3,-6] ]
array([[16, 17, 18, 19],
       [20, 21, 22, 23],
       [ 8, 9, 10, 11]])


此外,你还能更灵活的设定「行」和「列」中不同的索引,如下


arr[ [1,5,7,2], [0,3,1,2] ]
array([ 4, 23, 29, 10])


检查一下,上行代码获取的分别是第二行第一列、第六行第四列、第八行第二列、第三行第三列的元素,它们确实是 4, 23, 29 和 10。如果不用花式索引,就要写下面繁琐但等价的代码:



np.array( [ arr[1,0], arr[5,3],             arr[7,1], arr[2,2] ] )
array([ 4, 23, 29, 10])


最后,我们可以把交换列,把原先的 [0,1,2,3] 的列换成 [0,3,1,2]。


arr[:,[0,3,1,2]]
array([[ 0, 3, 1, 2],
       [ 4, 7, 5, 6],
       [ 8, 11, 9, 10],
       [12, 15, 13, 14],
       [16, 19, 17, 18],
       [20, 23, 21, 22],
       [24, 27, 25, 26],
       [28, 31, 29, 30]])





4总结



本帖讨论了 NumPy 的前三节,数组创建、数组存载和数组获取。同样把 numpy 数组当成一个对象,要学习它,无非就是学习怎么


  • 创建它:按步就班法、定定点法、一步登天法
  • 存载它:保存成 .npy, .txt 和 .csv 格式,下次加载即用
  • 获取它:一段用切片,一个用索引;有正规法、布尔法、花式法


等等,你好像还没教什么 numpy 数组硬核的东西呢,下帖讨论 NumPy 的后两节就教怎么


  • 变形它:重塑和打平,合并和分裂,元素重复和数组重复
  • 计算它:元素层面计算,线性代数计算,广播机制计算




回到引言的「数组转置」问题:



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


第 1, 2, 3 维度转置到第 2, 1, 3 维度,即将轴 0, 1, 2 转置到轴 1, 0, 2


解答:

数组转置的本质:交换每个轴 (axis) 的形状 (shape) 和跨度 (stride)。


四幅图解决问题:



原数组




内存块的样子




轴 0 和轴 1 互换





转置结果



用代码验证一下:


arr.transpose(1,0,2)
array([[[ 0, 1, 2, 3],
        [ 8, 9, 10, 11]],
       [[ 4, 5, 6, 7],
        [12, 13, 14, 15]]])


欧了!下篇讨论 NumPy 系列的「数组的变性」和「数组的计算」。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