Я столкнулся с этой проблемой при выравнивании изображений. Рассмотрим следующий массив
>>> import numpy as np
>>> arr = np.array([[[1, 2],
[3, 4]],
[[1, 2],
[3, 4]]])
>>> arr.shape
(2, 2, 2)
Я хочу преобразовать это в массив 4x2, где каждый вертикальный срез представляет собой сплющенное изображение.
.reshape(2, 4).TЭто позволяет добиться желаемого результата
>>> arr_flatten = arr.reshape(2, 4).T
>>> arr_flatten
[[1 1]
[2 2]
[3 3]
[4 4]]
.reshape(4, 2)Это не приводит к желаемому результату
>>> arr_flatten = arr.reshape(4, 2)
>>> arr_flatten
[[1 2]
[3 4]
[1 2]
[3 4]]
Почему второй подход не работает?
Другими словами: любое изменение формы, независимо от его параметра, сохраняет порядок данных (порядок, в котором вы записываете каждое значение на экране при печати массива, остается неизменным после любого изменения формы).
.T, с другой стороны, не сохраняет этот порядок (его единственная задача — изменить этот порядок).
Поэтому неудивительно, что data.reshape(whatever) не может быть таким же, как data.reshape(whatever).T. Проблема не в reshape части. Опять же, они не влияют на порядок данных. Вы можете связать по 20 .reshape с каждой стороны, они ничего не изменят в этом порядке (опять же под «порядком» я имею в виду порядок, в котором данные печатаются на экране). Проблема в .T. С одной стороны есть .T, а с другой нет. Зная, что фатально то, что какими бы reshape ни были, массивы должны быть разными, поскольку они даже не имеют одинакового порядка.






Два изменения формы создают массив по-разному. Думайте о .reshape(2,4) как о перемещении по массиву при подсчете элементов, и каждый раз, когда он достигает 4, он создает новую строку и перезапускает счет. Итак, со счетчиком в скобках идет 1 (1), 2 (2), 3 (3), 4 (4) новая строка 1 (1), 2 (2), 3 (3), 4 (4) . Для .reshape(4,2) он считает до 2 и начинает новый ряд. Итак, 1 (1), 2 (2) новая строка, 3 (1), 4 (2) новая строка, 1 (1), 2 (2) новая строка, 3 (1), 4 (1).
Следовательно, .reshape(2,4) производит
array([[1, 2, 3, 4],
[1, 2, 3, 4]])
И .reshape(4,2) производит.
array([[1, 2],
[3, 4],
[1, 2],
[3, 4]])
Очевидно, что их транспонирования не равны. Что касается того, почему человек дает правильный ответ, все сводится к значению данных и тому, как они упорядочены. В этом случае, поскольку изображения находятся на оси 0, .reshape(2,4) пересекает всю ось 0 перед созданием новой строки, поэтому дает правильный результат.
Таким образом, принцип работы .reshape() похож на чтение слов со страницы (слева направо, а затем сверху вниз), а затем запись их на страницу другого размера в том порядке, в котором вы их читаете?
С аргументами по умолчанию, да. Если вы посмотрите документацию reshape, там есть kwarg по умолчанию order = "C", который сообщает ему, что ему следует двигаться слева направо и сверху вниз (поскольку именно так определяются массивы в C). Если бы это было изменено на order = "F", то это было бы в стиле Фортрана и двигалось бы сверху вниз и слева направо (.reshape(2,4) тогда было бы [[1, 3, 2, 4], [1, 3, 2, 4]]).
@MagnusSesodia: если говорить прагматично: когда вы печатаете массив, изменение формы никогда не меняет порядок чисел. Меняется только расположение [ и ]. .T да. Таким образом, вы можете игнорировать все .reshape, чтобы ответить на свой вопрос: поскольку на одном, поскольку у вас есть .T, а на другом нет, это означает, что с одной стороны у вас другой порядок номеров массива, а с другой , у вас тот же порядок, что и в исходном массиве (только с разными [ / ] местами)
Хорошее объяснение, также стоит изучить различные шаги каждого массива, чтобы лучше понять разницу.
Из документов
You can think of reshaping as first raveling the array (using the given index order), then inserting the elements from the raveled array into the new array using the same kind of index ordering as was used for the raveling.. Играйте с разными фигурами, начиная сnp.arange(8).