разрезать массив, не зная его размеров

#python #numpy

#python #numpy

Вопрос:

Я хочу нарезать массив, не зная его размеров. Индексы ( start и end приведены в формате списка. Как это сделать? Спасибо.

Нарезать 1d массив

 import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
# idx: [2, 5)
print(a[2:5])
# [3, 4, 5]
 

Нарезать 2d массив

 import numpy as np
a = np.array([
[1, 2, 3],
[2, 3, 2],
[4, 5, 2]
])

start = [0, 1]
end = [1, 2]

print(a[start[0]:end[0], start[1]:end[1]])
 

Нарезать N-d массив?

 a = np.array([
    [[1, 0, 2],
    [2, 1, 0],
    [5, 6, 3]],
    
    [[2, 1, 3],
    [3, 2, 1],
    [1, 4, 6]]
])

start = [0, 0, 1]
end = [1, 1, 2]

result = a[start[0]:end[0], start[1]:end[1], start[2]:end[2]] # key point: how to adapt this?
print(result)
 

Комментарии:

1. Вам len(a.shape) нужно узнать количество измерений, а затем вы можете перебирать все измерения, чтобы узнать количество значений в измерении.

2. Это мысль. Позвольте мне попробовать.

Ответ №1:

Если у вас есть список начальных и конечных индексов, вы можете создать кортеж объектов среза и выполнить следующие действия, чтобы разрезать массив, не зная его размеров:

 a[tuple(slice(*indexes) for indexes in zip(start, end))]
 

Или:

 a[tuple(slice(st, en) for st, en in zip(start, end))]
 

Или:

 from itertools import starmap

a[tuple(starmap(slice, zip(start, end)))]
 

В действии:

 a = np.array([
    [[1, 0, 2],
    [2, 1, 0],
    [5, 6, 3]],
    
    [[2, 1, 3],
    [3, 2, 1],
    [1, 4, 6]]
])

start = [0, 0, 1]
end = [1, 1, 2]

result1 = a[start[0]:end[0], start[1]:end[1], start[2]:end[2]] # key point: how to adapt this?

result2 = a[tuple(slice(*indexes) for indexes in zip(start, end))] 

assert np.all(result2 == result2)