一、Numpy的花式索引Fancy Indexing
花式索引Fancy Indexing是 NumPy 采用的一个术语,用于描述使用整数数组进行索引。
1.举例:用元组来创建一个8x4的二维数组zeros,并循环赋值:
import numpy as np
arr = np.zeros((8, 4))
#为二维数组arr每行赋值
for i in range(8):
arr[i] = i
print(arr)
上面代码输出:
[[0. 0. 0. 0.]
[1. 1. 1. 1.]
[2. 2. 2. 2.]
[3. 3. 3. 3.]
[4. 4. 4. 4.]
[5. 5. 5. 5.]
[6. 6. 6. 6.]
[7. 7. 7. 7.]]
要按特定顺序选择arr数组行的子集,只需传递指定顺序的整数列表或 ndarray 即可,如下:
arr[[4, 3, 0, 6]] 传递了整数列表[4, 3, 0, 6],表示取二维数组arr的行索引位置为4、3、0、6的行并按此顺序输出子集:
[[4. 4. 4. 4.]
[3. 3. 3. 3.]
[0. 0. 0. 0.]
[6. 6. 6. 6.]]
也可以使用负数索引从后往前来选择相应的行组成子集。例如:
arr[[-3, -5, -7]],数组的最后一行表示-1,所以arr[[-3, -5, -7]]输出
[[5. 5. 5. 5.]
[3. 3. 3. 3.]
[1. 1. 1. 1.]]
2.使用多个索引数组来选择子集
举例:使用arange和reshape来创建一个值从0-31的8x4的二位数组,代码如下
arr = np.arange(32).reshape((8, 4))
print(arr)
输出结果如下:
[[ 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]]
如果我们传递两个索引数组来选择arr中的元素,会得到一个一维数组,比如:
arr[[1, 5, 7, 2], [0, 3, 1, 2]] 这相当于获取索引位置为第1行第0列(1,0)、第5行第3列(5,3)、第7行第1列(7,1)、第2行第2列(2,2)的元素,输出如下:
[ 4 23 29 10] 生成的是一维数组。
注意:使用与轴(维数)一样多的整数数组进行花式索引的结果始终是输出一维数组。
如果要选择形成二位数组输出,我们可以看下下面的这种用法:
arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]] 首先整数数组[1, 5, 7, 2]相当于选择了arr数组的第1,5,7,2行输出,然后使用[:, [0, 3, 1, 2]] 这里使用了冒号,表示每一行都按照第0、3、1、2列的顺序输出相应的元素,也可以理解为将列按照0、3、1、2的顺序重新排序了,整个arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]输出结果如下:
[[ 4 7 5 6]
[20 23 21 22]
[28 31 29 30]
[ 8 11 9 10]]
在使用花式索引的时候,如果我们将选择的子集赋值给了新的变量,则相应位置的元素值是复制给了新变量的。
3.转置数组和交换轴(类似于行列变换)以及 矩阵计算
用arr = np.arange(15).reshape((3, 5)) 生成一个3x5的二位数组,值从0-14。输出结果如下:
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
可以使用T进行行列转换,arr.T 输出结果如下(转换成5x3的二维数组):
[[ 0 5 10]
[ 1 6 11]
[ 2 7 12]
[ 3 8 13]
[ 4 9 14]]
在进行矩阵计算的时候,我们可以dot函数和T来计算内矩阵积,看如下代码示例:
import numpy as np
arr = np.array([[0, 1, 0], [1, 2, -2], [6, 3, 2], [-1, 0, -1], [1, 0, 1]])
print(arr.T)
print(arr)
result = np.dot(arr.T, arr)
print(result)
上面代码输出如下:
这是arr通过T转换后的数组
[[ 0 1 6 -1 1]
[ 1 2 3 0 0]
[ 0 -2 2 -1 1]]
这是arr数组
[[ 0 1 0]
[ 1 2 -2]
[ 6 3 2]
[-1 0 -1]
[ 1 0 1]]
这是arr.T @ arr 的乘积。
[[39 20 12]
[20 14 2]
[12 2 10]]
这个结果矩阵的第(0,0)元素的值39是这么来的,arr.T矩阵的第0行的元素乘以arr矩阵的第0列元素相应位置相乘的和,学过高数的应该都知道了,不行就百度下矩阵相乘。
矩阵乘积函数dot还可以用符号@来替换,两者等效,例如arr.T@arr
矩阵的转置(行列转换)还可以用swapaxes函数,例如arr.swapaxes(0, 1) 与 arr.T 等效,(0,1)是轴编号,swapaxes 同样返回数据视图,而不创建副本。