numpy的使用说明(三):numpy中切片和索引详解
原创
©著作权归作者所有:来自51CTO博客作者黄至尊qwe的原创作品,请联系作者获取转载授权,否则将追究法律责任
1、切片
1)numpy中数组切片与原生python切片的不同点
- 数组切片返回的是原始数组的视图,原生python切片返回的是原始数组的浅拷贝。
操作如下:
list1 = [1,2,3]
display(list1)
list2 = list1[1:]
display(list2)
# 此时,修改list2中某一个元素,查看原始列表的元素是否发生变化?
list2[0] = 666
display(list2)
display(list1)
array1 = np.array([1,3,5,2,4])
display(array1)
array2 = array1[2:]
display(array2)
# 此时,修改array2中某一个元素,查看原始数组的元素是否发生变化?
array2[0] = 888
display(array2)
display(array1)
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_切片](https://s2.51cto.com/images/blog/202208/02100052_62e885549938b44351.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
① 使用数组对象的copy方法,实现底层数据的复制,而不是返回底层数据的视图;
array3 = np.array([1,2,3,4,5,6])
display(array3)
array4 = array3.copy()
display(array4)
array4[2] = 666
display(array4)
display(array3)
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_numpy_02](https://s2.51cto.com/images/blog/202208/02100053_62e885550771110702.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
2)numpy中切片的使用
① 使用切片需要注意的知识点
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_切片_03](https://s2.51cto.com/images/blog/202208/02100053_62e885554dc2f83506.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
② 一张图帮你理解数组切片
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_python索引_04](https://s2.51cto.com/images/blog/202208/02100053_62e885559839a10237.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
③ 常用切片操作如下
a = np.arange(10)
display(a) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(a[:3]) # 0 1 2
print(a[3:6]) # 3 4 5
print(a[6:]) # 6 7 8 9
print(a[::]) # 0 1 2 3 4 5 6 7 8 9
print(a[:]) # 0 1 2 3 4 5 6 7 8 9
print(a[::3]) # 0 3 6 9
print(a[1::3]) # 1 4 7
print(a[2::3]) # 2 5 8
# 当start、stop、step为负数的时候,理解起来就稍微难一点;
print(a[::-1]) # 9 8 7 6 5 4 3 2 1 0
print(a[:-4:-1]) # 9 8 7
print(a[-4:-7:-1]) # 6 5 4
print(a[-7::-1]) # 3 2 1 0
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_python索引_05](https://s2.51cto.com/images/blog/202208/02100053_62e88555f0d2275623.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
④ 当你理解了那幅图,可以做一下如下几道题目,检验一下自己;
a = np.arange(10)
display(a)
print(a[-8:-2:1])
print(a[7:1:-1])
注意:上述两个切片是否存在问题,假如不存在,结果又是什么?如果你能回答正确这两个问题,python切片,就没有问题了。
3)当数组是多维数组时,可以使用array[高维, 低维]的方式,按维度进行索引或切片。
- 如果中括号[]中只写了一个维度的时候,就代表最高维;
- 对每一个维度,都可以使用上述的切片功能;
① 直接举例说明
b = np.arange(20).reshape(4,5)
display(b)
display(b[2,3])
display(b[1])
display(b[-1])
# -----------------------------------------------
display(b[1:3,2:4])
display(b[2,1:4])
display(b[0:3,1])
# -----------------------------------------------
display(b[1:3,:])
display(b[:,1])
display(b[::])
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_索引_06](https://s2.51cto.com/images/blog/202208/02100054_62e885564085e46223.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
② 怎么把一个二维数组的所有元素全部倒序过来?
c = np.arange(12).reshape(3,4)
display(c)
# ------------你可分步考虑一下---------------
display(c[::-1,:])
display(c[:,::-1])
display(c[::-1,::-1])
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_python切片_07](https://s2.51cto.com/images/blog/202208/02100054_62e88556611ab42476.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
2、索引
1)普通索引
a = np.arange(1,13,1).reshape(3,4)
display(a)
# 获取某一个元素:如下两种方式
display(a[1][2])
display(a[1,2])
# 获取某一行元素:如下两种方式
display(a[1])
display(a[1,:])
# 获取某一列元素
display(a[:,1])
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_切片_08](https://s2.51cto.com/images/blog/202208/02100054_62e88556b0fc464413.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
2)通过整数数组进行索引(这个比较有用)
- 当要选取的元素不连续时,可以提供一个索引数组来选择(或修改)对应索引位置
的元素。 - 通过整数数组索引,【返回的是原数组的拷贝,而不是视图】。
- 可以提供多个一维数组索引,此时会将每个数组的对应位置元素作为索引,返回对应的元素。
① 通过整数数组索引,获取数组中的元素(这个用的多一点);
a = np.arange(1,21,1).reshape(5,4)
display(a)
# 选取数组a中的第2、第4、第5行数据;
display(a[[1,3,4]])
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_索引_09](https://s2.51cto.com/images/blog/202208/02100054_62e88556e4f4883173.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
② 提供多个一维数组索引,获取数组中的元素(这种方式很特别,了解一下);
a = np.arange(1,21,1).reshape(5,4)
display(a)
# 下面这个代码获取的是对应位置组成的坐标的元素
# [1,2],[4,3],[4,2]
display(a[[1,4,4],[2,3,2]])
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_python切片_10](https://s2.51cto.com/images/blog/202208/02100055_62e885576506874862.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
③ 通过整数数组索引,【返回的是原数组的拷贝,而不是视图】;
a = np.arange(1,21,1).reshape(5,4)
display(a)
b = a[[1,3]]
display(b)
b[1,2] = 888
display(b)
display(a)
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_numpy_11](https://s2.51cto.com/images/blog/202208/02100055_62e885579f7a532451.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
注意:当返回的是原数组的拷贝的时候,相当于将原始数组复制了一份,在内存中重新开辟了一块儿空间,存储起来了。因此,当我修改任何一个数组,相互之间没有任何影响。
3)通过布尔数组进行索引
- 含义:我们可以提供一个布尔类型的数组(A),然后通过该数组(A)来对另外一个数组(B)进行索引(元素选取)。索引的原则为:如果为True,则选取对应位置的元素,否则不选取。
- 作用:通过布尔类型的数组进行索引是常见且实用的操作,我们通常用来进行元素选择(或过滤)操作。
① 通过布尔数组取一维数组中的元素
a = np.array([17,19,32,13,27,10,40])
a1 = a[[True,True,False,True,False,False,True]]
display(a1)
bool_index = a > 15
display(bool_index)
a2 = a[bool_index]
display(a2)
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_numpy_12](https://s2.51cto.com/images/blog/202208/02100055_62e88557eee5c3765.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
② 通过布尔数组取二维数组中的元素
b = np.arange(10,30).reshape(5,4)
display(b)
# 这个表示选取第1,2,4行;
b1 = b[[True,True,False,True,False]]
display(b1)
bool_index = b > 20
display(bool_index)
b2 = b[bool_index]
display(b2)
结果如下:
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_索引_13](https://s2.51cto.com/images/blog/202208/02100056_62e885584219d97396.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
③ 构造布尔数组的几种常用的运算符
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_索引_14](https://s2.51cto.com/images/blog/202208/02100056_62e8855880ed521413.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
操作如下
c = np.arange([15,18,19,23,24,28,30,35,37,40,41,45])
display(c)
c1 = c[c>25]
display(c1)
c2 = c[(c>20) & (c<35)]
display(c2)
c3 = c[(c<20) | (c>40)]
display(c3)
c4 = c[~(c>40)]
display(c4)
结果如下
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_numpy_15](https://s2.51cto.com/images/blog/202208/02100056_62e88558a4d1915990.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
④ 取出两个数组中相同的元素
a = np.array([1, 3, 9, 10])
b = np.array([1, 8, 6, 10])
# 对应位置的元素,会进行比较;
display(a[a == b])
结果如下
![在这里插入图片描述 numpy的使用说明(三):numpy中切片和索引详解_切片_16](https://s2.51cto.com/images/blog/202208/02100056_62e88558cdda494484.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)