Обратная операция суммирования на массиве NumPy - PullRequest
2 голосов
/ 02 апреля 2019

У меня есть строка кода, которая эффективно преобразует массивный массив из массива 400x8x8 в массив 160x160, и мне нужно повернуть процесс вспять, но я не могу понять обратное этой линии.

Я уже могу выполнить этот процесс, но он очень неэффективен и требует вложенных циклов, которых я хотел бы избежать в целях производительности.

Вот код, который мне сейчас нужен, чтобы полностью изменить процесс (160x160> 400x8x8):

       previousRow = 0
    for rowBlock in range(noBlocksOn1Axis):
        previousRow = rowBlock * blockSize  
        previousColumn = 0
        for columnBlock in range(noBlocksOn1Axis):
            previousColumn = columnBlock * blockSize
            block = 
            arrayY[previousRow:previousRow+blockSize, 
            previousColumn:previousColumn + blockSize]
            blocksList.append(block) 

А вот строка кода, которая изменяет 400x8x8> 160x160:

    xy = np.zeros((160,160), dtype = np.uint8)

    xy = np.vstack(np.hstack(overDone[20*i:20+20*i]) for i in 
    range(overDone.shape[0]//20))

Так есть ли идеи о том, как я могу выполнить эту строку кода в обратном порядке?

Спасибо: D

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

Изменение формы, изменение оси (или транспонирование осей) и изменение формы, чтобы получить overDone назад -

xy.reshape(20,8,20,8).swapaxes(1,2).reshape(400,8,8)

Подробнее о intuition behind nd-to-nd array transformation.

Сделайте его универсальным для обработки общих форм -

m,n = xy.shape
M,N = 20,20 # block size used to get xy
overDone_ = xy.reshape(M,m//M,N,n//N).swapaxes(1,2).reshape(-1,m//M,n//N)

Пробный прогон -

# Original input
In [21]: overDone = np.random.rand(400,8,8)

# Perform forward step to get xy
In [22]: xy = np.vstack(np.hstack(overDone[20*i:20+20*i]) for i in range(overDone.shape[0]//20))

# Use proposed approach to get back overDone
In [23]: out = xy.reshape(20,8,20,8).swapaxes(1,2).reshape(400,8,8)

# Verify output to be same as overDone
In [42]: np.array_equal(out,overDone)
Out[42]: True

Бонус:

Мы могли бы использовать те же векторизованные reshape+permute-axes шаги для создания xy для процесса пересылки -

xy = overDone.reshape(20,20,8,8).swapaxes(1,2).reshape(160,160)
0 голосов
/ 02 апреля 2019

Что не так с numpy.reshape?

my_array_3d = my_array.reshape((400, 8, 8))
my_array_2d = my_array.reshape((160, 160))
...