继续学习NumPy,今天学习以下3个章节:

7,NumPy高级索引
8,NumPy广播机制
9,NumPy遍历数组
numpy_test3.py :
import numpy as np

'''
7, NumPy高级索引
NumPy 与 Python 的内置序列相比,它提供了更多的索引方式。
在 NumPy 中还可以使用高级索引方式,比如整数数组索引、布尔索引以及花式索引
高级索引返回的是数组的副本(深拷贝),而切片操作返回的是数组视图(浅拷贝)。 1) 整数数组索引
整数数组索引,它可以选择数组中的任意一个元素,比如,选择第几行第几列的某个元素,
'''
print("-----------整数数组索引-------------")
#创建二维数组
arr1 = np.array([[1, 3], [5, 7], [9, 6]])
print('arr1 :', arr1)
#[0,1,2]代表行索引;[1,1,0]代表列索引
arr2 = arr1[[0,1,2],[1,1,0]]
print('arr2 :', arr2)
'''
arr1 : [ [1 3]
[5 7]
[9 6] ]
arr2 : [3 7 9]
分析:将行、列索引组合会得到 (0,1)、(1,1) 和 (2,0) ,它们分别对应着输出结果在原数组中的索引位置。
'''
#获取了 4*4 数组中的四个角上元素,它们对应的行索引是 [0,0] 和 [3,3],列索引是 [0,3] 和 [0,3]
arr3 = np.array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 12, 13, 14, 15]])
print('arr3 :', arr3)
row = np.array([[0,0],[3,3]])
col = np.array([[0,3],[0,3]])
#获取四个角的元素
arr4 = arr3[row,col]
print('arr4 :', arr4)
'''
arr3 : [ [ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15] ]
arr4 : [ [ 0 3]
[12 15] ]
分析:将行、列索引组合会得到 (0,0)、(0,3) 和 (3,0)、(3,3) ,它们分别对应着输出结果在原数组中的索引位置。
''' '''
也可以将切片所使用的:或省略号...与整数数组索引结合使用
'''
print("-----------将切片所使用的:或省略号...与整数数组索引结合使用-------------")
#对行列分别进行切片
arr5 = arr3[1:3,1:3]
print('arr5 :', arr5)
#行使用基础索引,对列使用高级索引
arr6 = arr3[1:3,[1,2]]
#显示切片后结果
print('arr6 :', arr6)
#对行使用省略号...
arr7 = arr3[...,2:]
print('arr7 :', arr7)
#对列使用省略号...
arr8 = arr3[2:,...]
print('arr8 :', arr8)
'''
arr3 : [ [ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15] ]
arr5 : [ [ 5 6]
[ 9 10] ]
arr6 : [ [ 5 6]
[ 9 10] ]
arr7 : [ [ 2 3]
[ 6 7]
[10 11]
[14 15] ]
arr8 : [ [ 8 9 10 11]
[12 13 14 15] ]
''' '''
2) 布尔数组索引
当输出的结果需要经过布尔运算(如比较运算)时,此时会使用到另一种高级索引方式,即布尔数组索引。
'''
print("-----------布尔数组索引-------------")
arr9 = np.array([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]])
print('arr9 :', arr9)
# 返回所有大于5的数字组成的数组
print('arr9[arr9 > 5] :', arr9[arr9 > 5])
'''
arr9 : [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
arr9[arr9 > 5] : [ 6 7 8 9 10 11]
'''
#可以使用补码运算符来去除 NaN(即非数字元素)
arr10 = np.array([np.nan, 1, 2, np.nan, 3, np.nan, 5, 6, 7])
print('arr10 :', arr10)
print('arr10[~np.isnan(arr10)] :', arr10[~np.isnan(arr10)])
#删除数组中非复数元素
arr11 = np.array([1, 2+3j, 3, 5, 3.2+4j, 3.2])
print('arr11 :', arr11)
print('arr11[np.iscomplex(arr11)] :', arr11[np.iscomplex(arr11)])
'''
arr10 : [nan 1. 2. nan 3. nan 5. 6. 7.]
arr10[~np.isnan(arr10)] : [1. 2. 3. 5. 6. 7.]
arr11 : [1. +0.j 2. +3.j 3. +0.j 5. +0.j 3.2+4.j 3.2+0.j]
arr11[np.iscomplex(arr11)] : [2. +3.j 3.2+4.j]
''' '''
3) 花式索引(拓展知识)
花式索引也可以理解为整数数组索引,但是它们之间又略有不同,花式索引也会生成一个新的副本。 如果原数组是二维数组,那么索引数组也需要是二维的,索引数组的元素值与被索引数组的每一行相对应
'''
print("-----------花式索引-------------")
arr12 = np.arange(32).reshape((8, 4))
print('arr12 :', arr12)
# 分别对应 第3行数据、第2行数据、第1行数据、第6行数据项
arr13 = arr12[[3, 2, 1, 6]]
print('arr13 :', arr13)
# 也可以使用倒序索引数组
arr14 = arr12[[-3, -2, -1, -6]]
print('arr14 :', arr14)
# 还可以同时使用多个索引数组,但这种情况下需要添加np.ix_
arr15 = arr12[np.ix_([1, 3, 4, 2], [0, 3, 1, 2])]
print('arr15 :', arr15)
'''
arr12 : [[ 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]] arr13 : [[12 13 14 15]
[ 8 9 10 11]
[ 4 5 6 7]
[24 25 26 27]] arr14 : [[20 21 22 23]
[24 25 26 27]
[28 29 30 31]
[ 8 9 10 11]] arr15 : [[ 4 7 5 6]
[12 15 13 14]
[16 19 17 18]
[ 8 11 9 10]] 其中 [1,3,4,2] 代表行索引,而 [0,3,1,2] 表示与行索引相对应的列索引值,也就是行中的元素值会按照列索引值排序。
比如,第一行元素,未排序前的顺序是 [4,5,6,7],经过列索引排序后变成了 [4,7,5,6]。
''' '''
8,NumPy广播机制
NumPy 中的广播机制(Broadcast)旨在解决不同形状数组之间的算术运算问题。
我们知道,如果进行运算的两个数组形状完全相同,它们直接可以做相应的运算。
'''
print("-----------NumPy广播机制-------------")
a1 = np.array([0.1, 0.2, 0.3, 0.4])
b1 = np.array([10, 20, 30, 40])
c1 = a1 * b1
print('c1 :', c1)
# c1 : [ 1. 4. 9. 16.]
'''
但如果两个形状不同的数组呢?它们之间就不能做算术运算了吗?当然不是!为了保持数组形状相同,NumPy 设计了一种广播机制,
这种机制的核心是对形状较小的数组,在横向或纵向上进行一定次数的重复,使其与形状较大的数组拥有相同的维度。 当进行运算的两个数组形状不同,Numpy 会自动触发广播机制。
'''
a2 = np.array([[0, 0, 0], [5, 10, 20], [10, 20, 30]])
# b数组与a数组形状不同
b2 = np.array([1, 2, 3])
c2 = a2 * b2
print('c2 :', c2)
'''
c2 : [[ 0 0 0]
[ 5 20 60]
[10 40 90]] 3x3 的二维 a2 数组 与 1x3 的一维 b2 数组相乘,本质上可以理解为 b2 数组在纵向上向下拓展 3 次(将第一行重复 3 次),
b2 变成了 [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
从而生成与 a2 数组相同形状的数组,之后再与 a2 数组进行运算。
''' '''
9, NumPy遍历数组
NumPy 提供了一个 nditer 迭代器对象,它可以配合 for 循环完成对数组元素的遍历。
'''
print("-----------NumPy遍历数组-------------")
arr16 = np.arange(0, 45, 5)
print('arr16 :', arr16)
arr17 = arr16.reshape(3, 3)
print('arr17 :', arr17)
# 使用nditer迭代器,并使用for进行遍历
for x in np.nditer(arr17):
print(x, end=",")
print("\n------------------------")
'''
arr16 : [ 0 5 10 15 20 25 30 35 40]
arr17 : [[ 0 5 10]
[15 20 25]
[30 35 40]]
0,5,10,15,20,25,30,35,40,
''' '''
1) 遍历顺序
在内存中,Numpy 数组提供了两种存储数据的方式,分别是 C-order(行优先顺序)与 Fortrant-order(列优先顺序)。
那么 nditer 迭代器又是如何处理具有特定存储顺序的数组呢?其实它选择了一种与数组内存布局一致的顺序,
之所以这样做,是为了提升数据的访问效率。 在默认情况下,当我们遍历数组中元素的时候,不需要考虑数组的存储顺序,这一点可以通过遍历上述数组的转置数组来验证。
'''
print("-----------遍历顺序-------------")
# 转置数组
arr18 = arr17.T
print('arr18 :', arr18)
for x in np.nditer(arr18):
print(x, end=",")
print("\n------------------------")
'''
arr18 : [[ 0 15 30]
[ 5 20 35]
[10 25 40]]
0,5,10,15,20,25,30,35,40,
可以看出,输出结果可以看出,arr17 和 arr17.T 转置数组,的遍历顺序是一样的,
也就是说,它们在内存中的存储顺序是一样的。
'''
# 转置数组,并copy方法生成数组副本,存储方式变更
arr19 = arr17.T.copy(order='C')
print('arr19 :', arr19)
for x in np.nditer(arr19):
print(x, end=",")
print("\n------------------------")
'''
arr19 : [[ 0 15 30]
[ 5 20 35]
[10 25 40]]
0,15,30,5,20,35,10,25,40,
''' '''
2) 指定遍历顺序
您可以通过 nditer 对象的order参数来指定数组的遍历的顺序。
'''
print("-----------指定遍历顺序-------------")
print(" C-order(行优先顺序)")
for x in np.nditer(arr17, order='C'):
print(x, end=",")
print("\n------------------------")
print(" F-order(列优先顺序)")
for x in np.nditer(arr17, order='F'):
print(x, end=",")
print("\n------------------------")
'''
C-order(行优先顺序)
0,5,10,15,20,25,30,35,40,
------------------------
F-order(列优先顺序)
0,15,30,5,20,35,10,25,40,
''' '''
3) 修改数组元素值
nditer 对象提供了一个可选参数op_flags,它表示能否在遍历数组时对元素进行修改。它提供了三种模式,如下所示:
(1) read-only
只读模式,在这种模式下,遍历时不能修改数组中的元素。
(2) read-write
读写模式,遍历时可以修改元素值。
(3) write-only
只写模式,在遍历时可以修改元素值。
'''
print("-----------遍历过程,修改数组元素值-------------")
arr20 = arr17.copy()
print("原数组是:", arr20)
for x in np.nditer(arr20, op_flags=['readwrite']):
x[...] = 2*x # 每个元素都乘2
print('修改后的数组是:', arr20)
'''
原数组是: [[ 0 5 10]
[15 20 25]
[30 35 40]]
修改后的数组是: [[ 0 10 20]
[30 40 50]
[60 70 80]]
''' '''
4) 外部循环使用
nditer 对象的构造函数有一个“flags”参数,它可以接受以下参数值: flags参数说明
参数值 描述说明
c_index 可以跟踪 C 顺序的索引。
f_index 可以跟踪 Fortran 顺序的索引。
multi_index 每次迭代都会跟踪一种索引类型。
external_loop 返回的遍历结果是具有多个值的一维数组。
'''
print("-----------外部循环使用-------------")
arr20 = arr17.copy()
print("原数组是:", arr20)
#修改后数组
print("修改后的一维数组")
for x in np.nditer(arr20, flags=['external_loop'], order='F'):
print(x)
print("\n------------------------")
'''
原数组是: [[ 0 5 10]
[15 20 25]
[30 35 40]]
修改后的一维数组
[ 0 15 30]
[ 5 20 35]
[10 25 40]
''' '''
5) 迭代多个数组
如果两个数组都能够被广播,那么 nditer 对象就可以同时对它们迭代。 假设数组 a3 的维度是 3*3,另一个数组 b3 的维度是 1*3 (即维度较小的数组 b3 可以被广播到数组 a3 中)
'''
print("-----------迭代多个数组,广播迭代-------------")
a3 = np.arange(0, 45, 5).reshape(3, 3)
print("a3 : ", a3)
b3 = np.array([1, 2, 3], dtype=int)
print("b3 : ", b3)
# 广播迭代
for x,y in np.nditer([a3, b3]):
print("%d:%d" % (x, y), end="; ")
print("\n------------------------")
'''
a3 : [[ 0 5 10]
[15 20 25]
[30 35 40]]
b3 : [1 2 3]
0:1; 5:2; 10:3; 15:1; 20:2; 25:3; 30:1; 35:2; 40:3;
'''
 
 

NumPy学习3的更多相关文章

  1. NumPy学习笔记 三 股票价格

    NumPy学习笔记 三 股票价格 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.&l ...

  2. NumPy学习笔记 二

    NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...

  3. NumPy学习笔记 一

    NumPy学习笔记 一 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...

  4. 数据分析之Pandas和Numpy学习笔记(持续更新)<1>

    pandas and numpy notebook        最近工作交接,整理电脑资料时看到了之前的基于Jupyter学习数据分析相关模块学习笔记.想着拿出来分享一下,可是Jupyter导出来h ...

  5. NumPy学习(索引和切片,合并,分割,copy与deep copy)

    NumPy学习(索引和切片,合并,分割,copy与deep copy) 目录 索引和切片 合并 分割 copy与deep copy 索引和切片 通过索引和切片可以访问以及修改数组元素的值 一维数组 程 ...

  6. NumPy学习(让数据处理变简单)

    NumPy学习(一) NumPy数组创建 NumPy数组属性 NumPy数学算术与算数运算 NumPy数组创建 NumPy 中定义的最重要的对象是称为 ndarray 的 N 维数组类型. 它描述相同 ...

  7. numpy 学习笔记

    numpy 学习笔记 导入 numpy 包 import numpy as np 声明 ndarray 的几种方法 方法一,从list中创建 l = [[1,2,3], [4,5,6], [7,8,9 ...

  8. numpy 学习总结

    numpy 学习总结 作者:csj更新时间:01.09 email:59888745@qq.com 说明:因内容较多,会不断更新 xxx学习总结: 回主目录:2017 年学习记录和总结 #生成数组/使 ...

  9. (转)Python数据分析之numpy学习

    原文:https://www.cnblogs.com/nxld/p/6058572.html https://morvanzhou.github.io/tutorials/data-manipulat ...

  10. Numpy学习1

    NumPy学习(1) 参考资料: http://www.cnblogs.com/zhanghaohong/p/4854858.html http://linusp.github.io/2016/02/ ...

随机推荐

  1. Qt编写安防视频监控系统54-轮询配置

    一.前言 视频监控系统中少不了用到视频轮询,按照设计的基本原则,先满足基本的用户需求,稳定跑起来,再去折腾更复杂的应用场景,于是本系统也做了个基本的视频轮询功能,可以设置轮询方案,给某个轮询方案设置轮 ...

  2. Qt编写地图综合应用25-echart动态交互

    一.前言 之前用echart组件做过各种效果,随着各种现场应用现场项目的增多,各种需求也都慢慢增加起来,为了满足各种不同类型的需求,近期又抽空重新整理和封装了echart类,主要就是增加了不少的js函 ...

  3. TotalUninstaller(Setup.ForcedUninstall.exe)可执行程序和源码的下载

    TotalUninstaller(Setup.ForcedUninstall.exe)可执行程序和源码的下载: 链接:https://pan.baidu.com/s/1uBiJ6z1RNVmBEUiF ...

  4. 《深入理解Mybatis原理》MyBatis配置解析过程

    配置解析主体方法 public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfi ...

  5. Android RNDIS gadget Windows免驱修改方案

    过程简单粗暴,拿到竞品的设备,然后使用UsbTreeView查看设备的相关描述符. 对比发现接口抽象描述符和接口描述符不一致,直接修改Linux RNDIS gadget 驱动,将驱动中有关的两个描述 ...

  6. 2021 年万圣节 Github 彩蛋

    记录每年 Github 万圣节彩蛋,也记录有来项目成长历程. 2021 万圣节彩蛋 2020 万圣节彩蛋

  7. Linux 压缩命令集合

    01. tar格式 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!) 02. gz格式 解压1:gunzi ...

  8. 「V 曲闲谈」《宠儿》——谁凌迟着梦想家

      反正个人博客啥都能写是吧.(   严格来说,这并不是对歌曲或者 PV 的解析,仅仅是记录这首歌带给我的一些感触.   参考:狐狸座 ver & 艾尔法 ver.   按照简介,歌曲的内容似 ...

  9. biancheng-Python爬虫教程

    http://c.biancheng.net/python_spider/ 网络爬虫又称网络蜘蛛.网络机器人,它是一种按照一定的规则自动浏览.检索网页信息的程序或者脚本.网络爬虫能够自动请求网页,并将 ...

  10. MQ---消息队列概念和使用场景

    消息队列概念和使用场景 声明:本文转自:MQ入门总结(一)消息队列概念和使用场景 写的很好,都不用自己在整理了,非常感谢该作者的用心. 一.什么是消息队列  消息即是信息的载体.为了让消息发送者和消息 ...