Подтвердить что ты не робот

Python: изменение размера существующего массива и заполнение нулями

Я думаю, что моя проблема должна быть очень простой, но я не могу найти никакой помощи в Интернете. Я очень новичок в Python, так что возможно, что Я пропускаю что-то очень очевидное.

У меня есть массив S, как этот [x x x] (one-dimensional). Теперь я создаю диагональная матрица, sigma, с np.diag(S) - пока что так хорошо. Теперь я хочу измените размер этого нового диагонального массива, чтобы я мог умножить его на другой массив, который У меня есть.

import numpy as np
...
shape = np.shape((6, 6)) #This will be some pre-determined size
sigma = np.diag(S) #diagonalise the matrix - this works
my_sigma = sigma.resize(shape) #Resize the matrix and fill with zeros - returns "None" - why?

Однако, когда я печатаю содержимое my_sigma, я получаю "None". Может кто-то угодить назовите меня в правильном направлении, потому что я не могу себе представить, что это должно быть так сложно.

Заранее благодарим за помощь!

Каспер

Графический

У меня есть это:

[x x x]

Я хочу это:

[x 0 0]
[0 x 0]
[0 0 x]
[0 0 0]
[0 0 0]
[0 0 0] - or some similar size, but the diagonal elements are important.
4b9b3361

Ответ 1

sigma.resize() возвращает None, потому что он работает на месте. np.resize(sigma, shape), с другой стороны, возвращает результат, но вместо заполнения с нулями, он прокладывает повторы массива.

Кроме того, функция shape() возвращает форму ввода. Если вы просто хотите предопределить форму, просто используйте кортеж.

import numpy as np
...
shape = (6, 6) #This will be some pre-determined size
sigma = np.diag(S) #diagonalise the matrix - this works
sigma.resize(shape) #Resize the matrix and fill with zeros

Однако это сначала сгладит ваш исходный массив, а затем восстановит его в заданную форму, уничтожив первоначальный порядок. Если вы просто хотите "набивать" нулями, вместо использования resize() вы можете просто напрямую индексировать в сгенерированную нулевую матрицу.

# This assumes that you have a 2-dimensional array
zeros = np.zeros(shape, dtype=np.int32)
zeros[:sigma.shape[0], :sigma.shape[1]] = sigma

Ответ 2

В версии 1.7.0 есть новая функция numpy numpy.pad, которая может сделать это в одной строке. Как и другие ответы, вы можете построить диагональную матрицу с np.diag перед заполнением. Кортеж ((0,N),(0,0)), используемый в этом ответе, указывает "сторону" матрицы, которую нужно наложить.

import numpy as np

A = np.array([1, 2, 3])

N = A.size
B = np.pad(np.diag(A), ((0,N),(0,0)), mode='constant')

B теперь равен:

[[1 0 0]
 [0 2 0]
 [0 0 3]
 [0 0 0]
 [0 0 0]
 [0 0 0]]

Ответ 3

Я вижу редактирование... вам нужно сначала создать нули, а затем переместить в него некоторые числа. np.diag_indices_from может быть вам полезен

bigger_sigma = np.zeros(shape, dtype=sigma.dtype)
diag_ij = np.diag_indices_from(sigma)
bigger_sigma[diag_ij] = sigma[diag_ij] 

Ответ 4

Еще одно чистое решение python -

a = [1, 2, 3]
b = []
for i in range(6):
    b.append((([0] * i) + a[i:i+1] + ([0] * (len(a) - 1 - i)))[:len(a)])

b теперь

[[1, 0, 0], [0, 2, 0], [0, 0, 3], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

Это отвратительное решение, я признаю это. Однако он иллюстрирует некоторые функции типа list, которые могут быть использованы.

Ответ 5

Это решение работает с функцией resize

Возьмем массив образцов

S= np.ones((3))
print (S)
# [ 1.  1.  1.]
d= np.diag(S) 
print(d)
"""
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]

"""

Эта дозировка работает, она просто добавляет повторяющиеся значения

np.resize(d,(6,3))
"""
adds a repeating value
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
"""

Эта работает

d.resize((6,3),refcheck=False)
print(d)
"""
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]]
"""