NumPy学习3
继续学习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的更多相关文章
- NumPy学习笔记 三 股票价格
NumPy学习笔记 三 股票价格 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.&l ...
- NumPy学习笔记 二
NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...
- NumPy学习笔记 一
NumPy学习笔记 一 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...
- 数据分析之Pandas和Numpy学习笔记(持续更新)<1>
pandas and numpy notebook 最近工作交接,整理电脑资料时看到了之前的基于Jupyter学习数据分析相关模块学习笔记.想着拿出来分享一下,可是Jupyter导出来h ...
- NumPy学习(索引和切片,合并,分割,copy与deep copy)
NumPy学习(索引和切片,合并,分割,copy与deep copy) 目录 索引和切片 合并 分割 copy与deep copy 索引和切片 通过索引和切片可以访问以及修改数组元素的值 一维数组 程 ...
- NumPy学习(让数据处理变简单)
NumPy学习(一) NumPy数组创建 NumPy数组属性 NumPy数学算术与算数运算 NumPy数组创建 NumPy 中定义的最重要的对象是称为 ndarray 的 N 维数组类型. 它描述相同 ...
- numpy 学习笔记
numpy 学习笔记 导入 numpy 包 import numpy as np 声明 ndarray 的几种方法 方法一,从list中创建 l = [[1,2,3], [4,5,6], [7,8,9 ...
- numpy 学习总结
numpy 学习总结 作者:csj更新时间:01.09 email:59888745@qq.com 说明:因内容较多,会不断更新 xxx学习总结: 回主目录:2017 年学习记录和总结 #生成数组/使 ...
- (转)Python数据分析之numpy学习
原文:https://www.cnblogs.com/nxld/p/6058572.html https://morvanzhou.github.io/tutorials/data-manipulat ...
- Numpy学习1
NumPy学习(1) 参考资料: http://www.cnblogs.com/zhanghaohong/p/4854858.html http://linusp.github.io/2016/02/ ...
随机推荐
- Qt编写地图综合应用47-经纬度地址互相转换
一.前言 地址经纬度互换的功能只有在线地图有,因为需要去服务器查询对应的数据,拿到返回的数据,百度地图中需要用到BMap.Geocoder来实现这两个功能的互换,他内置了getPoint函数负责将地址 ...
- Qt编写的项目作品20-百度地图综合应用(在线+离线+区域+下载)
一.功能特点 (一).省市区域地图封装类功能特点 同时支持闪烁点图.迁徙图.区域地图.世界地图.仪表盘等. 可以设置标题.提示信息.背景颜色.文字颜色.线条颜色.区域颜色等各种颜色. 可设置城市的名称 ...
- C#中使用ping命令测试远程主机网络通信是否正常
说明,使用ping工具 1.可以用来查询域名是否可以访问 2.可以用来查询域名对应的ip地址 如果远程服务器允许ping命令的前提下. 解决思路:主要使用了C#提供的Ping类,效率比较高,相应快 程 ...
- JSON解析的这6种方案,真香!
前言 在 Java 开发中,解析 JSON 是一个非常常见的需求. 不管是和前端交互.调用第三方接口,还是处理配置文件,几乎都绕不开 JSON. 这篇文章总结了6种主流的 JSON 解析方法,希望对你 ...
- 2024-12-28 AI智能体日报
- 永远不要轻易设置Oracle的隐藏参数,哪怕是DRM
这篇文章可能会存在较大争议,甚至颠覆一些人的固有思维. 因为关于Oracle的隐藏参数,江湖上一直都有两派对立的观点: 1.不要设置任何隐藏参数,只有当遇到特殊问题时在售后指导下临时使用,在问题解决后 ...
- UWP ManipulationStarted 移动图片或控件不要滑出父容器的判断
假设自定义一个用户控件用以在父容器Grid里拖动/移动: <UserControl x:Class="App6.Pic" xmlns="http://schemas ...
- .net core 用 identitymodel 请求token。
identitymodel 也有在Nuget里搜索和安装. identitymodel 扩展了HttpClient的一些方法用于token请求. 例如:client.RequestTokenAsyn ...
- 深入理解Java泛型、协变逆变、泛型通配符、自限定
禁止转载 重写了之前博客写的泛型相关内容,全部整合到这一篇文章里了,把坑都填了,后续不再纠结这些问题了.本文深度总结了函数式思想.泛型对在Java中的应用,解答了许多比较难的问题. 纯函数 协变 逆变 ...
- 引燃算力新基建,天翼云亮相DCIC2024第13届数据中心产业发展大会!
近日,由中国通信企业协会主办的"第13届数据中心产业发展大会暨AIDC智能算力生态合作展览会"在北京顺利举行.现场展示了天翼云"AIDC""紫金&qu ...