Пространственный способ:
import numpy as np
hires = np.array((6, 12))
lowres = np.array((2,4))
h, w = hires // lowres
m = np.arange(np.prod(lowres)).reshape(lowres)
print(m)
# [[0 1 2 3]
# [4 5 6 7]]
v = [0, 1, 4, 24, 36, 42]
i, j = np.unravel_index(v, hires)
w = m[i // h, j // w]
print(w)
# [0 0 1 0 4 6]
Пространственный неэффективный способ:
import numpy as np
hires = np.array((6, 12))
lowres = np.array((2,4))
h, w = hires // lowres
# DON'T DO THIS. INEFFICIENT
m = np.kron(np.arange(np.prod(lowres)).reshape(lowres), np.ones(h, w), )
print(m)
# [[0. 0. 0. 1. 1. 1. 2. 2. 2. 3. 3. 3.]
# [0. 0. 0. 1. 1. 1. 2. 2. 2. 3. 3. 3.]
# [0. 0. 0. 1. 1. 1. 2. 2. 2. 3. 3. 3.]
# [4. 4. 4. 5. 5. 5. 6. 6. 6. 7. 7. 7.]
# [4. 4. 4. 5. 5. 5. 6. 6. 6. 7. 7. 7.]
# [4. 4. 4. 5. 5. 5. 6. 6. 6. 7. 7. 7.]]
v = [0, 1, 4, 24, 36, 42]
w = m[np.unravel_index(v, hires)]
print(w)
# [0. 0. 1. 0. 4. 6.]
Основная идея здесь заключается в использовании np.unravel_index
преобразовать "плоский индекс" в кортеж координат, учитывая форму массива, в который вы собираетесь индексировать.
Например,
In [446]: np.unravel_index([0, 1, 4, 24, 36, 42], (6, 12))
Out[446]: (array([0, 0, 0, 2, 3, 3]), array([0, 1, 4, 0, 0, 6]))
Возвращает два индексных массива, которые вместе даюткоординаты 0-го, 1-го, 4-го и т. д. «сплющенных» элементов в массиве формы (6, 12).
Неэффективный в пространстве метод создает большой массив m
и затем находит w
путем индексации m
с этими координатами: w = m[np.unravel_index(v, hires)]
.
Более эффективный в пространстве метод просто целочисленно делит координаты на размер блока (в данном случае, 3 на 3), чтобы генерировать низкийкоординатыЭто избавляет от необходимости генерировать большую матрицу m
.Вместо этого мы можем использовать меньшую матрицу
In [447]: m = np.arange(np.prod(lowres)).reshape(lowres); m
Out[447]:
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
и индексировать в нее: w = m[i // h, j // w]
.
Возможно, вас также заинтересует np.ravel_multi_index
,которая является обратной величиной np.unravel_index
:
In [451]: np.ravel_multi_index((np.array([0, 0, 0, 2, 3, 3]), np.array([0, 1, 4, 0, 0, 6])), (6, 12))
Out[451]: array([ 0, 1, 4, 24, 36, 42])
Преобразует массивы координат i
и j
обратно в v
.