2012-02-12 2 views
22

Я думаю, что моя проблема должна быть очень простой, но я не могу найти никакой помощи в Интернете. Я очень новичок в 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". Может кто-то пожалуйста указать мне в правильном направлении, потому что я не могу себе представить, что это должно быть так сложно.

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

Casper

Графический:

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

[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. 
+0

Вы определяете shape(), diag() и resize(), или те, которые вы используете в библиотеке? – grieve

+0

resize() из библиотеки numpy, я должен был указать это. – casper

+0

Это numpy, не так ли? Если я правильно понимаю, у сигмы есть данные, но вы хотите сделать сигму более крупной и нулевой - заполнить новые элементы. Это верно? Если вам нужен новый нулевой массив, используйте 'numpy.zeros ((6,6))' – gfortune

ответ

17

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 
+0

Спасибо, это очень близко к тому, что мне нужно, но теперь моя новая матрица теряет свою диагональность, т. Е. Элементы, которые первоначально были по диагонали, не остаются там. Любая идея, как это исправить? – casper

+0

@ Каспер: см. Мое редактирование. – voithos

+0

Спасибо! Это прекрасно, спасибо за все ваши усилия, voithos! – casper

4

Я вижу редактирование ... вам нужно сначала создать нули, а затем переместить в него некоторые числа. 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] 
+0

Это похоже на работу, спасибо! Я рад видеть, что это довольно сложный процесс, и я не просто что-то пропустил. – casper

+0

Мне это нравится. Более читабельна и добавляет только то, что необходимо. Кроме того, использование 'sigma.dtype' - хорошая идея. – voithos

+0

Я предполагаю, что контекст вопроса - это вопрос SVD прямоугольной матрицы (с 'full_matrices = True') и создание реконструкции' A = USV''. В этом случае я предпочел бы этот тип решения. – Patrick

48

Существует новая функция NumPy в версии 1.7.0 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]] 
+1

** Спасибо за отправку ответа на обновление **. Перед моим +1 наши ответы были привязаны, но мой был pre numpy 1.7. Не уверен, что вы когда-нибудь получите ответ, потому что StackOverflow имеет «первый ответ выигрывает». Приятно видеть новую информацию ... –

0

Другой раствор чистого питона

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]] 

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

0

Это решение работает с 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.]] 
""" 
+0

Если вы измените второе измерение, а не первое, оно не будет – bold

Смежные вопросы