Numpy之二——切片和索引、副本和视图

it2026-01-18  4

副本和视图

numpy.ndarray.copy() 函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。数组切片操作返回的对象只是原数组的视图。对试图进行操作,会影响到原始的数据,它 们的物理内存是一致的。

切片和索引 数组的索引机制指的是用方括号[] 加序号的形式引用单个数组元素,可以应用于抽取元素、选取数组的几个元素和赋值。

整数索引 获取数组的单个元素,直接指定元素的索引。 import numpy as np x = np.array([1, 2, 3, 4, 5, 6, 7, 8]) print(x[2])#输出第三个元素 x = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33, 34, 35]]) print(x[2])#输出第三行 print(x[2][1])#输出第三行第二列 print(x[2, 1])#输出第三行第二列

输出

3 [21 22 23 24 25] 22 22 切片索引 切片操作是指抽取数组的一部分元素生成新数组。对python列表进行切片操作得到的数组是原数组的副本,对Numpy数据进行切片操作得到的数组是原数据的视图。(对副本操作不会改变原数据,对视图操作会改变原数据) (1) 对一维数组的切片 import numpy as np x = np.array([1, 2, 3, 4, 5, 6, 7, 8]) print(x[0:2])#打印前两个元素 print(x[1:5:2])#第一个到第四个元素,步长为2进行打印 print(x[2:])#从第二个元素开始打印,一直到最后一个元素 print(x[:2])#打印索引为0 1 两个元素 print(x[-2:])#打印倒数1 2 两个元素 print(x[:])#打印全部元素 print(x[::-1])#倒序打印所有元素

输出

[1 2] [2 4] [3 4 5 6 7 8] [1 2] [7 8] [1 2 3 4 5 6 7 8] [8 7 6 5 4 3 2 1]

抽取数组的一部分,必须使用切片语法,方括号内几个冒号将数字隔开:(start:stop:step)。其中省去start,numpy默认为0,省去stop,numpy默认为最大索引值,省去step,numpy默认为1。 (2) 对二维数组切片

import numpy as np x = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33, 34, 35]]) print(x[0:2]) #输出前两行 print(x[1:5:2])#输出第一,三,五行 print(x[2:])#输出第三,四,五行 print(x[:2])#输出第一,二 行 print(x[-2:])#输出倒数两行 print(x[:-2])#输出倒数第二行之前的行数 print(x[:])#打印全部 print(x[2, :])#打印第三行,全部列 print(x[:, 2])#打印所有行,第三列 print(x[0, 1:4])#打印第一行的二三两列 print(x[1:4, 0])#打印第一到三行,第一列 print(x[1:3, 2:4])#打印第一,二两行的二三两列 print(x[:, :])#打印所有行所有列

输出

[[11 12 13 14 15] [16 17 18 19 20]] [[16 17 18 19 20] [26 27 28 29 30]] [[21 22 23 24 25] [26 27 28 29 30] [31 32 33 34 35]] [[11 12 13 14 15] [16 17 18 19 20]] [[26 27 28 29 30] [31 32 33 34 35]] [[11 12 13 14 15] [16 17 18 19 20] [21 22 23 24 25]] [[11 12 13 14 15] [16 17 18 19 20] [21 22 23 24 25] [26 27 28 29 30] [31 32 33 34 35]] [21 22 23 24 25] [13 18 23 28 33] [12 13 14] [16 21 26] [[18 19] [23 24]] [[11 12 13 14 15] [16 17 18 19 20] [21 22 23 24 25] [26 27 28 29 30] [31 32 33 34 35]]

逗号前,对行操作;逗号后,对列操作。 (3) dots索引 NumPy 允许使用…表示足够多的冒号来构建完整的索引列表。

import numpy as np x = np.random.randint(1, 100, [2, 2, 3]) print(x) print(x[1, ...])#第一个维度的索引为0 1,此处直接取第一维度的第二个索引的全部内容 print(x[..., 2])#第三个维度的索引为0 1 2 ,此处直接取第三个维度的数值

输出

[[[94 75 76] [74 38 44]] [[88 59 52] [47 2 76]]] [[88 59 52] [47 2 76]] [[76 44] [52 76]]

(4) 整数数组索引 方括号内传入多个索引值,可以同时选择多个元素。 例1:一维数组

import numpy as np x = np.array([1, 2, 3, 4, 5, 6, 7, 8]) r = [0, 1, 2] print(x[r])# 同时输出索引为0 1 2 的三个值 r = [0, 1, -1] print(x[r])#同时输出索引为0 1 7的三个值

输出:

[1 2 3] [1 2 8]

例2:二维数组

import numpy as np x = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33, 34, 35]]) r = [0, 1, -1] print(x[r])#打印1 2 5行 r = [0, 1, 2] c = [2, 3, 4] y = x[r, c] print(y)#打印(0, 2)(1, 3)(2, 4)三个值

输出

[[11 12 13 14 15] [16 17 18 19 20] [31 32 33 34 35]] [13 19 25]

例3:多个数组情况

import numpy as np x = np.array([1, 2, 3, 4, 5, 6, 7, 8]) r = np.array([[0, 1],[3, 4]]) print(x[r])#输出x中索引0 1和索引为3 4的值 x = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33, 34, 35]]) r = np.array([[0, 1],[3, 4]]) print(x[r])#打印第一、二和第四、五行 #获取四个角上元素的办法 r = np.array([[0, 0], [4, 4]])# 行索引是0 0 4 4 c = np.array([[0, 4], [0, 4]])# 列索引是0 4 0 4 y = x[r, c] print(y)# 按照方位输出四个角上的值

输出:

[[1 2] [4 5]] [[[11 12 13 14 15] [16 17 18 19 20]] [[26 27 28 29 30] [31 32 33 34 35]]] [[11 15] [31 35]

例4:借助切片:与整数数组的组合

import numpy as np x = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33, 34, 35]]) y = x[0:3, [1, 2, 2]]#输出0 1 2三行中的第2 3 3 三列 print(y)

输出

[[12 13 13] [17 18 18] [22 23 23]]

例5:numpy.take(a, indices,axis=None, mode=‘raise’)

import numpy as np #一维 x = np.array([1, 2, 3, 4, 5, 6, 7, 8]) r = [0, 1, 2] print(np.take(x, r))#输出索引为0 1 2的三个数 #二维 x = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33, 34, 35]]) r = [0, 1, 2] print(np.take(x, r, axis=0))#输出1 2 3 三行(axis=0) r = [0, 1, 2] c = [2, 3, 4] print(np.take(x, [r, c]))#输出第一行中索引为0 1 2和2 3 4的值

输出

[1 2 3] [[11 12 13 14 15] [16 17 18 19 20] [21 22 23 24 25]] [[11 12 13] [13 14 15]]

注意:numpy中使用切片数组时,生成的数组是原数组的视图,即:改变一个另一个也会发生变化。numpy中使用整数数组索引,是原数组的副本,即:改变一个,另一个不会随之而变。

import numpy as np a=np.array([[1,2],[3,4],[5,6]]) b = a[0:1,0:1] b[0, 0] = 2 print(a[0, 0] == b)

输出:

[[ True]]

结论:numpy中使用切片数组时,生成的数组是原数组的视图。

import numpy as np a = np.array([[1,2],[3,4],[5,6]]) b = a[0, 0] b = 2 print(a[0, 0] == b)

输出:

False

结论:numpy中使用整数数组索引,是原数组的副本。

(5) 布尔索引 通过一个布尔数组来索引目标数组 例1:

import numpy as np x = np.array([1, 2, 3, 4, 5, 6, 7, 8]) y = x > 5# y是一个bool数组 print(y) print(x[x > 5]) x = np.array([np.nan, 1, 2, np.nan, 3, 4, 5]) y = np.logical_not(np.isnan(x))# numpy.logical_not(x)返回x非逻辑后的布尔值 print(x[y]) x = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33, 34, 35]]) y = x >25 print(y) print(x[x > 25])

输出

[False False False False False True True True] [6 7 8] [1. 2. 3. 4. 5.] [[False False False False False] [False False False False False] [False False False False False] [ True True True True True] [ True True True True True]] [26 27 28 29 30 31 32 33 34 35]

例2:

import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 2 * np.pi, 50) # 0到2pi取50个点 y = np.sin(x) plt.plot(x, y) # 画出y = f(x)的曲线 mask = y >= 0 #mask是一个布尔数组,大于0的值为True,小于0的值为False plt.plot(x[mask], y[mask], 'bo')#将这些点画出,形状为‘bo’ mask = np.logical_and(y >= 0, x <= np.pi / 2)#在前面mask的基础上逻辑与小于pi/2的值 plt.plot(x[mask], y[mask], 'go')#将mask为true的值用'go'画出 plt.show()

输出 数组迭代 除for循环,Numpy另外一种优雅的遍历方法。 apply_along_axis(func1d, axis, arr) 例子:

import numpy as np x = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33, 34, 35]]) y = np.apply_along_axis(np.sum, 0, x)#列的和 print(y) y = np.apply_along_axis(np.sum, 1, x)#行的和 print(y) y = np.apply_along_axis(np.mean, 0, x)#列的均值 print(y) y = np.apply_along_axis(np.mean, 1, x)#行的均值 print(y) def my_func(x): return (x[0] + x[-1]) * 0.5 y = np.apply_along_axis(my_func, 0, x)#对列采用自定义函数 print(y) y = np.apply_along_axis(my_func, 1, x)#对行采用自定义函数 print(y)

输出:

[105 110 115 120 125] [ 65 90 115 140 165] [21. 22. 23. 24. 25.] [13. 18. 23. 28. 33.] [21. 22. 23. 24. 25.] [13. 18. 23. 28. 33.]
最新回复(0)