#python #arrays #numpy #numpy-ndarray
Вопрос:
У меня есть массив, представляющий видео. В настоящее время он настроен следующим образом: первый элемент представляет собой массив всех значений первого пикселя на всех различных временных этапах, затем второй элемент относится ко второму пикселю и так далее. Я хочу, чтобы первым элементом был массив из всех пикселей на первом временном шаге.
Так что для двух кадров видео 2х2 я бы хотел
[
[
[a1, a2, a3], [b1, b2, b3]
],
[
[c1, c2, c3], [d1, d2, d3]
]
]
стать
[
[
[a1, b1],
[c1, d1]
],
[
[a2, b2],
[c2, d2]
],
[
[a3, b3],
[c3, d3]
],
]
Моя текущая реализация заключается в следующем:
def remap_image(seq):
# seq = np.array(seq)
s = seq.shape
a = np.zeros((s[2], s[0], s[1]))
for x, px in enumerate(tqdm(seq)):
for y, py in enumerate(px):
for p_counter, value in enumerate(py):
a[p_counter][x][y] = value/100.
return a
Это работает как задумано, однако этот подход невероятно медленный. Есть ли какой-нибудь более быстрый способ сделать это?
Комментарии:
1. Похоже, у вас есть (2,2,3) форма, и вы хотите перенести ее в (3,2,2)
2.
seq.transpose(2, 0, 1)
3. @MateenUlhaq работает отлично, спасибо!
Ответ №1:
Вы можете использовать einops с лучшей семантикой. В вашем случае работает следующий простой код.
from einops import rearrange
def remap_image(seq):
return rearrange(seq, 'w h t -> t w h')
Комментарии:
1. Классная упаковка. Очевидно, я снимался в ней, но после этого никогда не использовал ее. В конце концов, это дополнительная зависимость.
Ответ №2:
Следуя тому, что сказал Матин Ульхак, просто
def remap_image(seq):
return seq.transpose(2, 0, 1)
Ответ №3:
Я не уверен, что это будет намного быстрее, но вы могли бы использовать zip():
a = [
[
["a1", "a2", "a3"], ["b1", "b2", "b3"]
],
[
["c1", "c2", "c3"], ["d1", "d2", "d3"]
]
]
b = (list(map(list,zip(*r))) for r in a)
b = list(map(list,zip(*b)))
print(b)
[
[
['a1', 'b1'],
['c1', 'd1']
],
[
['a2', 'b2'],
['c2', 'd2']
],
[
['a3', 'b3'],
['c3', 'd3']
]
]
Если ваши данные находятся в массиве numpy, то b = np.transpose(a,axes=(2,0,1))
сделайте это напрямую и очень быстро.