Я хочу создать квадратную матрицу, скажем, 4X4, элементы которой взяты из вектора длиной 16. Эта векторная запись будет расположена в столбце матрицы. Предположим, что u — вектор длины 16, а M — матрица размера 4x4. Тогда M(1,1)=u(1), M(2,1)=u(2), M(3,1)=u(3), M(4,1)=u(4), M(1,2)=u(5), M(2,2)=u(6), M(3,2)=u(7) и скоро.
Это код, который я написал:
import numpy as np
Nx = Ny = 4
u0 = np.zeros([Nx*Ny, 1])
U0 = np.zeros([Nx, Ny])
aa = 0
for j in range(Ny):
for i in range(Nx):
U0[i][j] = u0[i+aa]
if (i%Nx) == 3:
aa = aa+4
else:
aa = aa
где Nx=Ny=4, а u0 — вектор длины 16.
После запуска кода вот результат:
:79: Предупреждение об устаревании: преобразование массива с ndim > 0 в скаляр устарело и в будущем приведет к ошибке. Прежде чем выполнять эту операцию, убедитесь, что вы извлекли один элемент из массива. (Устаревшая версия NumPy 1.25.) U0[i][j]=u0[i+aa]
Может кто-нибудь помочь мне интерпретировать этот результат? А что не так с моим кодом?
Кстати, в целом эту операцию можно выполнить, изменив форму например u0.rehape((4,4), order='F')
Инструмент @Vitalizzare для изменения формы действительно работает. Большое спасибо.
Хотя требуемую операцию можно выполнить путем изменения формы, например u.rehape((4,4), order='F')
, первоначальный подход может быть разумным в некоторых ситуациях копирования данных. Итак, давайте заставим это работать.
Проблема, с которой вы столкнулись, связана с тем, что технически вы работаете не с вектором, а с двумерным массивом. Таким образом, выражение типа u0[i+aa]
возвращает не скаляр, а вектор с одним элементом. Его по-прежнему можно использовать в качестве скаляра при присваивании, и то, что вы видите, — это не ошибка, а просто предупреждение об устаревании. Чтобы избавиться от этого предупреждения и гарантировать, что код будет работать с будущими версиями Numpy, вам нужно добавить дополнительный индекс для получения скаляра, например u0[i+aa, 0]
.
Я бы сделал дополнительные исправления, которые могут вас заинтересовать:
import numpy as np
Nx = Ny = 4
vector = np.arange(Nx*Ny).reshape(-1, 1) # get a vertical vector
matrix = np.zeros([Nx, Ny], dtype=vector.dtype) # keep dtype of the vector as long as possible
start = 0
for column in range(Ny):
matrix[:, column] = vector[start:start+Nx, 0]
start += Nx
print('vector:', vector, '\nmatrix:', matrix, sep='\n')
vector:
[[ 0]
[ 1]
[ 2]
[ 3]
[ 4]
[ 5]
[ 6]
[ 7]
[ 8]
[ 9]
[10]
[11]
[12]
[13]
[14]
[15]]
matrix:
[[ 0 4 8 12]
[ 1 5 9 13]
[ 2 6 10 14]
[ 3 7 11 15]]
Такое полезное объяснение. Спасибо за новые для меня знания.
Извините, почему мы сохраняем матрицу как векторный тип данных?
@Margi Если вы спросите о фрагменте кода dtype=vector.dtype
, это сделано для того, чтобы избежать путаницы из-за преобразования типов. Например, когда вещественному массиву присваиваются комплексные числа, вы теряете мнимую часть. В следующем примере вы сохраняете 1, но отбрасываете 1j: vector = np.array([1+1j]); matrix = np.array([[0]]); matrix[0, 0] = vector[0]
. Или, когда все ваши данные — целые числа, вам вряд ли захочется найти в результате дробную часть.
Не могли бы вы отредактировать свой код, добавив определения
u0
иU0
?