参考链接: Indexing
参考链接: Advanced indexing and index tricks
参考链接: numpy.newaxis
实验1: 单个元素索引
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> x = np.arange(10)
>>> x[2]
2
>>> x[-2]
8
>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>>
>>>
实验2: x[1,3]比x[1][3]效率更高,因为后者需要产生一个临时的中间变量.
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> x = np.arange(10)
>>> x.reshape(2,5)
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> x.resize(2,5)
>>> x
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> x.shape
(2, 5)
>>> x[1,3]
8
>>> x[(1,3)]
8
>>> x[1][3]
8
>>> x[1]
array([5, 6, 7, 8, 9])
>>>
>>> x[1,-1]
9
>>> x[(1,-1)]
9
>>>
>>> x[0]
array([0, 1, 2, 3, 4])
>>> x[0][2]
2
>>>
>>>
实验3: 使用切片
注意: 不同于列表和元组的切片,这里并不会返回一个拷贝copy,而是返回一个视图view,这是处于效率上的考虑
>>>
>>> x = np.arange(10)
>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> x[2:5]
array([2, 3, 4])
>>> x[:-7]
array([0, 1, 2])
>>> x[1:7:2]
array([1, 3, 5])
>>> y = np.arange(35).reshape(5,7)
>>> y
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, 32, 33, 34]])
>>> y[1:5:2,::3]
array([[ 7, 10, 13],
[21, 24, 27]])
>>>
>>>
实验4: 使用数组进行索引
注意: 使用列表和使用数组或者元组不用,
python默认arr[i, j]等效于arr[(i, j)].
注意使用数组索引返回的是拷贝copy而不是视图view,
返回的结果和原始数组互不影响.
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> x = np.arange(10,1,-1)
>>> x
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>> x[np.array([3, 3, 1, 8])]
array([7, 7, 9, 2])
>>> xx = x[np.array([3, 3, 1, 8])]
>>> xx
array([7, 7, 9, 2])
>>> xx[0] = 20200910
>>> xx
array([20200910, 7, 9, 2])
>>> x
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>> x[np.array([3, 3, 1, 8])]
array([7, 7, 9, 2])
>>> x[3] = 88888
>>> x
array([ 10, 9, 8, 88888, 6, 5, 4, 3, 2])
>>> x[np.array([3, 3, 1, 8])]
array([88888, 88888, 9, 2])
>>> xx
array([20200910, 7, 9, 2])
>>> x[np.array([3, 3, 1, 8])] = 7777
>>> x
array([ 10, 7777, 8, 7777, 6, 5, 4, 3, 7777])
>>> x[np.array([3, 3, 1, 8])]
array([7777, 7777, 7777, 7777])
>>> xx
array([20200910, 7, 9, 2])
>>>
>>>
>>>
>>> # 数组索引中的元素可以使用负数
>>> x = np.arange(10,1,-1)
>>> x
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>> x[np.array([3, 3, 1, 8])]
array([7, 7, 9, 2])
>>> array([7, 7, 9, 2])
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
array([7, 7, 9, 2])
NameError: name 'array' is not defined
>>> x[np.array([3, 3, 1, 8])]
array([7, 7, 9, 2])
>>>
>>> # 数组索引中的元素可以使用负数
>>> x[np.array([3,3,-3,8])]
array([7, 7, 4, 2])
>>> # 下标不可以越界
>>> x[np.array([3, 3, 20, 8])]
Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
x[np.array([3, 3, 20, 8])]
IndexError: index 20 is out of bounds for axis 0 with size 9
>>> x[np.array([3, 3, -20, 8])]
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
x[np.array([3, 3, -20, 8])]
IndexError: index -20 is out of bounds for axis 0 with size 9
>>> x[np.array([3, 3, -9, 8])]
array([ 7, 7, 10, 2])
>>> x[np.array([3, 3, 9, 8])]
Traceback (most recent call last):
File "<pyshell#34>", line 1, in <module>
x[np.array([3, 3, 9, 8])]
IndexError: index 9 is out of bounds for axis 0 with size 9
>>> x[np.array([3, 3, 8, 8])]
array([7, 7, 2, 2])
>>>
>>> # 返回的形状和索引数组相同,返回结果的元素和类型和被索引数组相同
>>> x[np.array([[1,1],[2,3]])]
array([[9, 9],
[8, 7]])
>>>
>>>
实验5: # 使用列表作为索引,返回的是拷贝而不是视图 # 使用切片作为索引,返回的是视图而不是拷贝 # 使用数组作为索引,返回的是拷贝而不是视图
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> # 使用列表作为索引,返回的是拷贝而不是视图
>>> x = np.arange(10,1,-1)
>>> xx = x[[0,1]]
>>> x
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>> xx
array([10, 9])
>>> x[0] = 2020
>>> xx[1] = 20200910
>>> x
array([2020, 9, 8, 7, 6, 5, 4, 3, 2])
>>> xx
array([ 10, 20200910])
>>> # 两者互不影响
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> # 使用切片作为索引,返回的是视图而不是拷贝
>>> x = np.arange(10,1,-1)
>>> xx = x[:2]
>>> x
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>> xx
array([10, 9])
>>> x[0] = 20200910
>>> xx[1] = 8888
>>> x
array([20200910, 8888, 8, 7, 6, 5,
4, 3, 2])
>>> xx
array([20200910, 8888])
>>> # 两者相互影响
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> # 使用数组作为索引,返回的是拷贝而不是视图
>>> x = np.arange(10,1,-1)
>>> index = np.array([0,1])
>>> index
array([0, 1])
>>> xx = x[index]
>>> x
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>> xx
array([10, 9])
>>> x[0] = 20200910
>>> xx[1] = 9999
>>> x
array([20200910, 9, 8, 7, 6, 5,
4, 3, 2])
>>> xx
array([ 10, 9999])
>>>
>>>
实验6: # 使用多维数组来索引
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> y = np.arange(35).reshape(5,7)
>>> y
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, 32, 33, 34]])
>>> y[np.array([0,2,4]), np.array([0,1,2])]
array([ 0, 15, 30])
>>> # 两个数组作为索引,他们形状必须相同,
>>> # 返回的元素是分别从这两个数组中取数,
>>> # 这两个数分别作为行索引和列索引来从原数组中取
>>>
>>> y[np.array([0,2,4]), np.array([0,1])]
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
y[np.array([0,2,4]), np.array([0,1])]
IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,)
>>> # 两个数组作为索引,他们形状必须相同
>>>
>>>
>>> # 单个数可以广播,可以看作两个数组
>>> y[np.array([0,2,4]), 1]
array([ 1, 15, 29])
>>> y[np.array([[0,2,4]]), 1]
array([[ 1, 15, 29]])
>>> y[np.array([[0,2,4],[2,0,1]]), 1]
array([[ 1, 15, 29],
[15, 1, 8]])
>>> y[np.array([[0,2,4],[2,0,1]]), np.array([0,2,4])]
array([[ 0, 16, 32],
[14, 2, 11]])
>>>
>>>
>>> # 单个数组,就是索引原数组的头一维
>>> y[np.array([0,2,4])]
array([[ 0, 1, 2, 3, 4, 5, 6],
[14, 15, 16, 17, 18, 19, 20],
[28, 29, 30, 31, 32, 33, 34]])
>>>
>>>
实验7: # 使用多维布尔数组来索引
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> y = np.arange(35).reshape(5,7)
>>> b = y>20
>>> y
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, 32, 33, 34]])
>>> b
array([[False, False, False, False, False, False, 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, True, True, True, True]])
>>> y[b]
array([21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34])
>>> b[:,5]
array([False, False, False, True, True])
>>> y[b[:,5]]
array([[21, 22, 23, 24, 25, 26, 27],
[28, 29, 30, 31, 32, 33, 34]])
>>>
>>>
>>> x = np.arange(30).reshape(2,3,5)
>>> x
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]]])
>>> b = np.array([[True, True, False], [False, True, True]])
>>> b
array([[ True, True, False],
[False, True, True]])
>>>
>>> x[b]
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]])
>>> # 布尔数组和整数的数组索引方式有所不同
>>> # 整数数组是在单个维度上索引
>>> # 而布尔数组可以同时在多个维度上一次性筛选出符合条件的元素
>>> # For example, using a 2-D boolean array of shape (2,3) with four True elements to select rows from a 3-D array of shape (2,3,5) results in a 2-D result of shape (4,5)
>>> 形状为(2,3)而且有4个元素为True的布尔数组来索引一个形状为(2,3,5)的多维数组,
SyntaxError: invalid syntax
>>> # 形状为(2,3)而且有4个元素为True的布尔数组来索引一个形状为(2,3,5)的多维数组,
>>> # 可以得到形状为(4,5)的多维数组
>>>
实验8: # 混合使用多维数组和切片来索引
注意: 数组和切片混合使用来索引时,两者并不耦合,他们的使用是相互独立的
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> y = np.arange(35).reshape(5,7)
>>> y
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, 32, 33, 34]])
>>> y[np.array([0, 2, 4]), 1:3]
array([[ 1, 2],
[15, 16],
[29, 30]])
>>> # 在索引中数组和切片是相互独立的
>>> # This is equivalent to:
>>> # 等效于
>>> y[:, 1:3][np.array([0, 2, 4]), :]
array([[ 1, 2],
[15, 16],
[29, 30]])
>>> y[np.array([0, 2, 4])][:,1:3]
array([[ 1, 2],
[15, 16],
[29, 30]])
>>>
>>> # 切片和广播布尔数组混合使用
>>> b = y > 20
>>> b
array([[False, False, False, False, False, False, 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, True, True, True, True]])
>>> b[:,5]
array([False, False, False, True, True])
>>> y[b[:,5],1:3]
array([[22, 23],
[29, 30]])
>>>
>>>
实验9: # np.newaxis以及省略号的使用
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> y = np.arange(35).reshape(5,7)
>>> y.shape
(5, 7)
>>> y[:,np.newaxis,:].shape
(5, 1, 7)
>>>
>>>
>>> x = np.arange(5)
>>> x
array([0, 1, 2, 3, 4])
>>> x[:,np.newaxis] + x[np.newaxis,:]
array([[0, 1, 2, 3, 4],
[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6],
[3, 4, 5, 6, 7],
[4, 5, 6, 7, 8]])
>>>
>>>
>>> # 省略号可以用来指明对剩余维度上的全选操作
>>> z = np.arange(81).reshape(3,3,3,3)
>>> z[1,...,2]
array([[29, 32, 35],
[38, 41, 44],
[47, 50, 53]])
>>> # 等效于:
>>> z[1,:,:,2]
array([[29, 32, 35],
[38, 41, 44],
[47, 50, 53]])
>>>
>>>
实验10: # 赋值时需要数组形状相同或者可广播.不同类型数据之间赋值时候,值可能会发生变化.
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> x = np.arange(10)
>>> # 我们可以对选择获取到的数组的子集进行赋值
>>> # 注意赋值是形状必须要相等或者可以广播
>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> # 单个值可以广播
>>> x[2:7] = 1
>>> x
array([0, 1, 1, 1, 1, 1, 1, 7, 8, 9])
>>>
>>> # 相同形状的赋值
>>> x = np.arange(10)
>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> x[2:7] = np.arange(5)
>>> x
array([0, 1, 0, 1, 2, 3, 4, 7, 8, 9])
>>>
>>>
>>> # 不同类型数据之间赋值时,值可能会发生变化,也可能抛出异常
>>> x
array([0, 1, 0, 1, 2, 3, 4, 7, 8, 9])
>>> x[1] = 1.2
>>> x[1]
1
>>> x
array([0, 1, 0, 1, 2, 3, 4, 7, 8, 9])
>>> x[1] = 20200910.2
>>> x[1]
20200910
>>> x
array([ 0, 20200910, 0, 1, 2, 3,
4, 7, 8, 9])
>>> x[1] = 1.2j
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
x[1] = 1.2j
TypeError: can't convert complex to int
>>>
>>>
>>>
>>> # 一个微妙的例子,重复数据赋值并不会进行累加
>>> x = np.arange(0, 50, 10)
>>> x
array([ 0, 10, 20, 30, 40])
>>> x[np.array([1, 1, 3, 1])] += 1
>>> x
array([ 0, 11, 20, 31, 40])
>>>
>>> # 等效于:
>>> x = np.arange(0, 50, 10)
>>> x
array([ 0, 10, 20, 30, 40])
>>> x[np.array([1, 1, 3, 1])] = x[np.array([1, 1, 3, 1])] + 1
>>> x
array([ 0, 11, 20, 31, 40])
>>>
>>>
>>>
实验11: # 使用元组可以作为数量可变的索引. 使用省略号的方式. 作为索引使用时,列表和元组的功能不同,列表会自动转化为ndarray多维数组,而元组则不会,它只会分别在相应的各个维度上筛选索引.
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> z = np.arange(81).reshape(3,3,3,3)
>>> z
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, 32],
[33, 34, 35]],
[[36, 37, 38],
[39, 40, 41],
[42, 43, 44]],
[[45, 46, 47],
[48, 49, 50],
[51, 52, 53]]],
[[[54, 55, 56],
[57, 58, 59],
[60, 61, 62]],
[[63, 64, 65],
[66, 67, 68],
[69, 70, 71]],
[[72, 73, 74],
[75, 76, 77],
[78, 79, 80]]]])
>>> indices = (1,1,1,1)
>>> z[indices]
40
>>>
>>>
>>> indices1 = (1,1,1,slice(0,2))
>>> z[indices1]
array([39, 40])
>>> # 等效于:
>>> z[1,1,1,0:2]
array([39, 40])
>>>
>>>
>>> indices = (1,1,1)
>>> z[indices]
array([39, 40, 41])
>>>
>>> indices = (1,1)
>>> z[indices]
array([[36, 37, 38],
[39, 40, 41],
[42, 43, 44]])
>>>
>>> indices = (1,)
>>> z[indices]
array([[[27, 28, 29],
[30, 31, 32],
[33, 34, 35]],
[[36, 37, 38],
[39, 40, 41],
[42, 43, 44]],
[[45, 46, 47],
[48, 49, 50],
[51, 52, 53]]])
>>>
>>>
>>>
>>> # 使用省略号
>>> indices = (1, Ellipsis, 1)
>>> z[indices]
array([[28, 31, 34],
[37, 40, 43],
[46, 49, 52]])
>>> z[1,...,1]
array([[28, 31, 34],
[37, 40, 43],
[46, 49, 52]])
>>> # 以上两者等效
>>>
>>>
>>>
>>>
>>> # 作为索引时,列表和元组的功能不同
>>> z[(1,1,1,1)] # returns a single value
40
>>> # 使用元组则返回单个数
>>> z[[1,1,1,1]] # produces a large array
array([[[[27, 28, 29],
[30, 31, 32],
[33, 34, 35]],
[[36, 37, 38],
[39, 40, 41],
[42, 43, 44]],
[[45, 46, 47],
[48, 49, 50],
[51, 52, 53]]],
[[[27, 28, 29],
[30, 31, 32],
[33, 34, 35]],
[[36, 37, 38],
[39, 40, 41],
[42, 43, 44]],
[[45, 46, 47],
[48, 49, 50],
[51, 52, 53]]],
[[[27, 28, 29],
[30, 31, 32],
[33, 34, 35]],
[[36, 37, 38],
[39, 40, 41],
[42, 43, 44]],
[[45, 46, 47],
[48, 49, 50],
[51, 52, 53]]],
[[[27, 28, 29],
[30, 31, 32],
[33, 34, 35]],
[[36, 37, 38],
[39, 40, 41],
[42, 43, 44]],
[[45, 46, 47],
[48, 49, 50],
[51, 52, 53]]]])
>>> z[[1,1,1,1]].shape
(4, 3, 3, 3)
>>> z[(1,1,1,1)].shape
()
>>> z[np.array([1,1,1,1])].shape
(4, 3, 3, 3)
>>> # 列表和元组不同,列表会自动转为ndarray多维数组,
>>> # 而元组则不会自动转化,它是在相应各个维度上取索引
>>> # 这就是元组和列表的区别
>>>
>>>
>>>
实验12: # 使用函数np.nonzero()返回的元组直接作为索引.
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> import numpy as np
>>> x = np.array([[1,0,0], [0,2,0], [1,1,0]])
>>> x
array([[1, 0, 0],
[0, 2, 0],
[1, 1, 0]])
>>> index = np.nonzero(x)
>>> index
(array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64))
>>> # 返回的是一个元组
>>> # 第一个元素包含的信息是非零元素的行索引
>>> # 第二个元素包含的信息是非零元素的列索引
>>> x[index]
array([1, 2, 1, 1])
>>> # 获取所有非零元素
>>> x[np.array([0, 1, 2, 2]),np.array([0, 1, 0, 1])]
array([1, 2, 1, 1])
>>> # 同样的方法来获取所有非零元素
>>>
>>>
>>>
>>> type(index)
<class 'tuple'>
>>>
>>>
>>>