Создание матрицы из векторных записей и предупреждение об устаревании от NumPy

Я хочу создать квадратную матрицу, скажем, 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 и U0?

Vitalizzare 26.06.2024 11:29

Кстати, в целом эту операцию можно выполнить, изменив форму например u0.rehape((4,4), order='F')

Vitalizzare 26.06.2024 11:34

Инструмент @Vitalizzare для изменения формы действительно работает. Большое спасибо.

Margi 27.06.2024 08:28
Почему в 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
3
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Хотя требуемую операцию можно выполнить путем изменения формы, например u.rehape((4,4), order='F'), первоначальный подход может быть разумным в некоторых ситуациях копирования данных. Итак, давайте заставим это работать.

Проблема, с которой вы столкнулись, связана с тем, что технически вы работаете не с вектором, а с двумерным массивом. Таким образом, выражение типа u0[i+aa] возвращает не скаляр, а вектор с одним элементом. Его по-прежнему можно использовать в качестве скаляра при присваивании, и то, что вы видите, — это не ошибка, а просто предупреждение об устаревании. Чтобы избавиться от этого предупреждения и гарантировать, что код будет работать с будущими версиями Numpy, вам нужно добавить дополнительный индекс для получения скаляра, например u0[i+aa, 0].

Я бы сделал дополнительные исправления, которые могут вас заинтересовать:

  • обеспечить одинаковый тип данных;
  • отказаться от ненужного задания;
  • обращаться к ячейке с помощью кортежа индексов, а не цепочки индексации;
  • используйте нарезку, чтобы продвинуть итерации глубже в Numpy, если это возможно.
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 28.06.2024 07:05

Извините, почему мы сохраняем матрицу как векторный тип данных?

Margi 28.06.2024 07:33

@Margi Если вы спросите о фрагменте кода dtype=vector.dtype, это сделано для того, чтобы избежать путаницы из-за преобразования типов. Например, когда вещественному массиву присваиваются комплексные числа, вы теряете мнимую часть. В следующем примере вы сохраняете 1, но отбрасываете 1j: vector = np.array([1+1j]); matrix = np.array([[0]]); matrix[0, 0] = vector[0]. Или, когда все ваши данные — целые числа, вам вряд ли захочется найти в результате дробную часть.

Vitalizzare 28.06.2024 08:28

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