Numpy矩阵的切片(slicing)和索引(indexing)

切片(slicing)操作

Numpy中的多维数据的切片操作和Python中对于list的切片操作是一样的。参数由start,stop,step三个部分构成。

import numpy as np

arr = np.arange(12)
print 'array is:', arr

slice_one = arr[:4]
print 'slice begins at 0 and ends at 4 is:', slice_one

slice_two = arr[7:10]
print 'slice begins at 7 and ends at 10 is:', slice_two

slice_three = arr[0:12:4]
print 'slice begins at 0 and ends at 12 with step 4 is:', slice_three
array is: [ 0  1  2  3  4  5  6  7  8  9 10 11]
slice begins at 0 and ends at 4 is: [0 1 2 3]
slice begins at 7 and ends at 10 is: [7 8 9]
slice begins at 0 and ends at 12 with step 4 is: [0 4 8]

以上是numpy操作一维数据的例子,如果是多维数组,只需在每个维度之间用 逗号 隔开。

注意:切片都是前闭后开,即切片结果包括start,但是不包括stop

# coding: utf-8
import numpy as np

arr = np.arange(12).reshape((3, 4))
print 'array is:'
print arr

# 取第一维的索引 1 到索引 2 之间的元素,也就是第二行
# 取第二维的索引 1 到索引 3 之间的元素,也就是第二列和第三列
slice_one = arr[1:2, 1:3]
print 'first slice is:'
print slice_one

# 取第一维的全部
# 按步长为 2 取第二维的索引 0 到末尾 之间的元素,也就是第一列和第三列
slice_two = arr[:, ::2]
print 'second slice is:'
print slice_two
array is:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
first slice is:
[[5 6]]
second slice is:
[[ 0  2]
 [ 4  6]
 [ 8 10]]

对于维数超过 3 的多维数组,还可以通过 '...' 来简化操作

# coding: utf-8
import numpy as np

arr = np.arange(24).reshape((2, 3, 4))

print arr[1, ...]               # 等价于 arr[1, :, :]
print arr[..., 1]               # 等价于 arr[:, :, 1]
[[12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]]
[[ 1  5  9]
 [13 17 21]]

索引(indexing)操作

对于多维数组来说,最常见的操作就是获取一个特定位置的值,如下所示:

# coding: utf-8
import numpy as np

arr = np.array([
    [1, 2, 3, 4],
    [2, 4, 6, 8],
    [3, 6, 9, 12],
    [4, 8, 12, 16]
])
print '第二行第二列的值:', arr[1, 1]
第二行第二列的值: 4

相比之下,Python对于list获取同一位置的操作如下:

# coding: utf-8
arr = [
    [1, 2, 3, 4],
    [2, 4, 6, 8],
    [3, 6, 9, 12],
    [4, 8, 12, 16]
]
print '第二行第二列的值:', arr[1][1]
try:
    print '第二行第二列的值(尝试用 Numpy 的方式获取):', arr[1, 1]
except Exception as e:
    print str(e)
第二行第二列的值: 4
第二行第二列的值(尝试用 Numpy 的方式获取): list indices must be integers, not tuple

相比之下可能二维数组对于同一操作来说差别并不大,试想如果是一个10维数组,那么执行这个标准操作Python索引list就需要10对[],而用numpy操作只需要写1对。

获取多个元素

事实上,在Numpy的索引操作方式 'x = arr[obj]' 中,obj不仅仅是一个用逗号分开的数字序列,还可以是更复杂的内容。

1.用逗号分隔的数组序列

  • 数组序列的长度要和多维数组的维度一致
  • 序列中每个数组的长度要一致
import numpy as np

arr = np.array([
    [1, 2, 3, 4],
    [2, 4, 6, 8],
    [3, 6, 9, 12],
    [4, 8, 12, 16]
])

print arr[[0, 2], [3, 1]]
[4 6]

对于上面这个例子,先选择第1行和第3行,然后再选择第1行的第4列,第3行的第2列组成新的数组。

2.boolean/mask index

所谓boolean index就是利用一个boolean表达式的形式确定索引,比如下例

array([[1, 2, 3, 4],
       [2, 4, 6, 8],
       [3, 6, 9, 12],
       [4, 8, 12, 16]])

要取其中大于 5 的元素:

import numpy as np

arr = np.array([[1, 2, 3, 4],
                [2, 4, 6, 8],
                [3, 6, 9, 12],
                [4, 8, 12, 16]])
mask = arr > 5

print 'boolean mask is:'
print mask

print arr[mask]
boolean mask is:
[[False False False False]
 [False False  True  True]
 [False  True  True  True]
 [False  True  True  True]]
[ 6  8  6  9 12  8 12 16]

切片和索引的异同

切片和索引都是获取数组中元素的方法,不过两者又有差异:

  1. 切片得到的是原多维数组的一个 视图(view) 修改切片中的内容也会导致原数组的值发生变化
  2. 切片得到的是连续的或按照一定步长连续排列的值,而索引得到的是任意位置的值,自由度更大一些。

转自: Numpy操作多维数组

你可能感兴趣的:(python)