Транспонировать ND список списков

1. Я использую cv2.imread для чтения большого изображения в массиве numpy (1234 * 1624 * 3)

2. Я использую cv2.dnn.blobFromImage, чтобы преобразовать его в (1,3,1234,1624) массив numpy

3. Я использую tolist(), чтобы преобразовать его в 4D-список в списках.

Моя проблема:

Как транспонировать ось этого списка

от (1,3,1234,1624) до (1,1234,1624,3)?

Сначала я попробовал np.transpose(image, (0, 2, 3, 1)), а затем tolist(), но это оказалось очень медленным. Поэтому я хочу транспонировать в виде списка.

Я проверил вопрос ниже, он кажется быстрым, но может транспонировать только 2D-список Транспонировать список списков

Очень признателен!!

Обновлять:

У меня есть список с именем temp.

len(temp)=1len(temp[0])=3len(temp[0][0])=1234len(temp[0][0][0])=1624

и я хочу перенести его ось на

len(temp)=1len(temp[0])=1234len(temp[0][0])=1624len(temp[0][0][0])=3

Как быть с temp1=list(map(list, zip(*temp))?

Используйте идиоматическое выражение zip(*zip(*items))

norok2 03.07.2019 08:31

Я пробовал temp1=list(map(list, zip(zip(*temp)))) но у меня не работает

Bill Huang 03.07.2019 08:46

Извините, я неправильно понял, трюк с двойным zip работает только для итераторов вложенности 1 уровня. Я думаю, что NumPy самый быстрый. Зачем вам нужно конвертировать его в list?

norok2 03.07.2019 08:48

Мне нужно отправить запрос в формате Json на обслуживание Tensorflow. Я обнаружил, что ndnumpy (1,3,1234,1624).tolist() намного быстрее, чем ndnumpy (1,1234,1624,3).tolist()

Bill Huang 03.07.2019 08:52

(1,3,1234,1624) - это форма массива ndnumpy

Bill Huang 03.07.2019 08:53

Этот массив транспонируется, np.transpose(image, (0, 2, 3, 1)) должен быть быстрым, так как он создает представление, а не копию. Выполнение tolist() на tolist может быть немного медленнее (чем image на np.transpose(image, (0, 2, 3, 1))), потому что оно, вероятно, включает копирование. Но это должно быть проще и быстрее, чем пытаться сделать эквивалентное транспонирование со списками.

hpaulj 03.07.2019 09:14

Я знаком с идиомой zip* для транспонирования простого вложенного списка, я бы поэкспериментировал, чтобы придумать эквивалент для этого четырехмерного вложения (на самом деле трехмерного, поскольку мы можем игнорировать первый размер одного измерения). Даже с этим я, вероятно, буду проверять свои результаты на версии с массивом, что легко понять.

hpaulj 03.07.2019 09:17
np.transpose(image, (0, 2, 3, 1)) очень быстро. Однако выполнение tolist() в массиве (1,1234,1624,3) numpy занимает в 5 раз больше, чем tolist() в массиве (1,3,1234,1624) numpy на моей машине.
Bill Huang 03.07.2019 09:19

Создание вложенного списка с этим небольшим внутренним размером 3 будет дорогостоящим, как бы вы это ни делали. У вас будет миллион лиатов размером 3 и указатели на каждый.

hpaulj 03.07.2019 09:46

@hpaulj, не могли бы вы поделиться своим кодом? Большое спасибо!

Bill Huang 03.07.2019 09:52
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
10
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это можно сделать без numpy и чисто функционально, но это некрасиво:

from itertools import starmap, repeat

a = np.ones((1,3,1234,1624)).tolist()
b = list(map(list, map(map, repeat(list), map(starmap, repeat(zip), starmap(zip, a)))))
np.shape(b)
# (1, 1234, 1624, 3)

Спасибо за ответ! np.ones((1,3,1234,1624)).tolist()+list(map(list, map(map, repeat(list), map(starmap, repeat(zip), starmap(zip, a))))) занимает только половину времени np.transpose(image, (0, 2, 3, 1))+tolist() на моей машине! Это много!

Bill Huang 03.07.2019 12:04

Тем не менее, я немного смущен тем, как работает эта карта и почтовый индекс. Можете ли вы просто объяснить, хочу ли я обобщить список N-D другой формы?

Bill Huang 03.07.2019 12:30

@BillHuang Боюсь, это то, на что я способен. Я не думаю, что это хорошо обобщает (выражения становятся все длиннее и длиннее). Что касается объяснения. Мы можем поменять местами только соседние оси с помощью zip, поэтому мы должны построить желаемое перемешивание из таких обменов. Обмены выглядят следующим образом: поменять местами оси 0 и 1: zip(*a) ; поменять местами оси 1 и 2: starmap(zip, a) ; поменять местами оси 2 и 3: map(starmap, repeat(zip), a) и т. д. В Python3 все эти генераторы возвращают значения, поэтому нам нужно форсировать списки на дополнительном шаге.

Paul Panzer 03.07.2019 12:52

Итак, начинаем --> (1, 3, 1234, 1624) Далее,starmap(zip, a) --> (1, 1234, 3, 1624) (поменяем местами оси 1 и 2) Далее,map(starmap, repeat(zip), starmap(zip, a))) --> (1, 1234, 1624, 3) (поменяем местами оси 2 и 3) Я правильно понимаю? Тогда что map(list, map(map, repeat(list), ) делает снаружи? Большое спасибо за Ваш ответ! @PaulPanzer

Bill Huang 04.07.2019 03:02

@BillHuang да, пока это правильно. Как я уже сказал, они создают не списки, а генераторы. Генератор - это что-то вроде "приостановленного цикла for", вам нужно перебрать его или сопоставить со списком или кортежем, иначе он ничего не делает. Как и в случае со свопами, эти генераторы создаются с разной глубиной вложенности, поэтому нам приходится администрировать приведение list через maps и вложенные maps.

Paul Panzer 04.07.2019 03:57

Другие вопросы по теме