Python数据分析NumPy和pandas(五、NumPy高维数组的数学计算 2)

一、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.使用多个索引数组来选择子集

举例:使用arangereshape来创建一个值从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 同样返回数据视图,而不创建副本。

猜你喜欢

转载自blog.csdn.net/FreedomLeo1/article/details/142789731