【问题标题】:Indexing numpy array with list of slices用切片列表索引 numpy 数组
【发布时间】:2020-01-30 14:51:47
【问题描述】:

我有一个slices 列表,并使用它们来索引numpy 数组。

arr = np.arange(25).reshape(5, 5)
# 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]])

slice_list = list(map(lambda i: slice(i, i+2), [1, 2]))
# [slice(1, 3, None), slice(2, 4, None)]

print(arr[slice_list])
# == arr[1:3, 2:4]
# [[ 7  8]
#  [12 13]]

这工作正常,但如果我的切片少于维度数,它会中断 我要索引的数组。

arr3d = arr[np.newaxis, :, :]  # dims: [1, 5, 5]
arr3d[:, slice_list]
# IndexError: only integers, slices (`:`), ellipsis (`...`),(`None`) 
#  numpy.newaxis and integer or boolean arrays are valid indices

以下示例仍然有效:

arr3d[:, slice_list[0], slice_list[1]]
arr3d[[slice(None)] + slice_list]
arr3d[:, [[1], [2]], [2, 3]]

有没有办法可以使用切片列表来索引具有更多维度的数组。 我想做这样的事情:

arr[..., slice_list]
arr[..., slice_list, :]
arr[:, slice_list, :]

不考虑数组的维度并计算出有多少[slice(None)]*X 我必须在我的slice_list 的两侧垫上。

【问题讨论】:

  • @user3483203 太棒了!

标签: python arrays numpy indexing


【解决方案1】:

您可以使用切片元组和省略号对象来做到这一点。只需将所有要用于索引的元素放入一个元组并将其用作索引:

import numpy as np

arr = np.arange(24).reshape(2, 3, 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]]]
slice_tup = tuple(map(lambda i: slice(i, i+2), [1, 2]))
print(slice_tup)
# (slice(1, 3, None), slice(2, 4, None))
print(arr[slice_tup])
# [[[20 21 22 23]]]

# arr[..., slice_list]
print(arr[(Ellipsis, *slice_tup)])
# [[[ 6  7]
#   [10 11]]
# 
#  [[18 19]
#   [22 23]]]

# arr[..., slice_list, :]
print(arr[(Ellipsis, *slice_tup, slice(None))])
# [[[20 21 22 23]]]

# arr[:, slice_list, :]
print(arr[(slice(None), *slice_tup, slice(None))])
# IndexError: too many indices for array

【讨论】:

  • 好的,但是我必须合并列表/元组,我不能直接使用arr[..., slice_tuple, :]
  • @scleronomic 不,因为这与arr[(Ellipsis, (slice(1, 3, None), slice(2, 4, None)), slice(None))] 相同(即嵌套元组)。对于这些情况,最好有* 解包语法,就像函数调用一样,所以你可以做类似arr[..., *slice_tup, :] 的事情,但目前不允许这样做(公平地说是一种极端情况)。但是你可以print(arr[(Ellipsis, *slice_tup, slice(None))]),这可能会更好一些(实际上我想我会更新答案以使用它)。
猜你喜欢
  • 1970-01-01
  • 2017-07-03
  • 2017-06-24
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多