изменение значений диагонали матрицы в numpy - PullRequest
30 голосов
/ 31 марта 2012

как можно изменить значения диагонали матрицы в numpy?

Я проверил Numpy изменить диагональ ndarray , но функция там не реализована в Numpy v 1.3.0.

Допустим, у нас есть массив np.array, и я хочу установить все значения диагонали в 0.

Ответы [ 7 ]

41 голосов
/ 31 марта 2012

Вы пробовали numpy.fill_diagonal? Смотрите следующий ответ и это обсуждение . Или следующее из документации (хотя в данный момент не работает):

http://docs.scipy.org/doc/numpy/reference/generated/numpy.fill_diagonal.html

13 голосов
/ 01 апреля 2012

Если вы используете версию numpy, в которой нет fill_diagonal ( правильный способ для установки диагонали в постоянную) или diag_indices_from, вы можете сделать это довольно легко нарезка массива:

# assuming a 2d square array
n = mat.shape[0]
mat[range(n), range(n)] = 0

Это намного быстрее, чем явный цикл в Python, потому что цикл происходит в C и потенциально векторизован.

Одна приятная вещь в этом заключается в том, что вы также можете заполнить диагональ списком элементов, а не постоянным значением (как diagflat, но для изменения существующей матрицы вместо создания новой). Например, это установит диагональ вашей матрицы на 0, 1, 2, ...:

# again assuming 2d square array
n = mat.shape[0]
mat[range(n), range(n)] = range(n)

Если вам нужно поддерживать больше форм массива, это более сложно (вот почему fill_diagonal хорош ...):

m[list(zip(*map(range, m.shape)))] = 0

(Вызов list необходим только в Python 3, где zip возвращает итератор.)

11 голосов
/ 15 июня 2013

Вот еще один хороший способ сделать это.Если вы хотите одномерное представление главной диагонали массива, используйте:

A.ravel()[:A.shape[1]**2:A.shape[1]+1]

Для i-го супердиагонального использования:

A.ravel()[i:max(0,A.shape[1]-i)*A.shape[1]:A.shape[1]+1]

Для i-го субдиагонального использования:

A.ravel()[A.shape[1]*i:A.shape[1]*(i+A.shape[1]):A.shape[1]+1]

Или вообще, для i-й диагонали, где главная диагональ равна 0, субдиагонали отрицательны, а супердиагонали положительны, используйте:

A.ravel()[max(i,-A.shape[1]*i):max(0,(A.shape[1]-i))*A.shape[1]:A.shape[1]+1]

Это просматривает , а не копии, поэтому они будут работать быстрее для извлечения диагонали, но любые изменения, внесенные в новый объект массива, будут применяться к исходному массиву.На моей машине они работают быстрее, чем функция fill_diagonal при установке постоянной основной диагонали, но это не всегда так.Их также можно использовать для назначения массива значений диагонали, а не только константе.

Примечания: для небольших массивов может быть быстрее использовать атрибут flat массива NumPy.Если скорость является основной проблемой, возможно, стоит сделать A.shape[1] локальной переменной.Кроме того, если массив не является смежным, ravel() вернет копию, поэтому для присвоения значений выделенному срезу необходимо будет творчески срезать исходный массив, использованный для генерации выделенного среза (если он смежный) или использовать атрибут flat.

Кроме того, изначально планировалось, что в NumPy 1.10 и более поздних версиях метода диагональных массивов будет возвращаться представление вместо копии.Это изменение еще не было сделано, но, надеюсь, в какой-то момент этот трюк, чтобы получить представление, больше не будет необходим.См http://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.diagonal.html

7 голосов
/ 21 февраля 2014

минимальная.Код.

X[np.diag_indices_from(X)] = 0.

screenshot

1 голос
/ 24 октября 2014

Вы можете сделать следующее.

Предполагается, что ваша матрица имеет матрицу 4 * 4.

indices_diagonal = np.diag_indices(4)

yourarray[indices_diagonal] = Val
1 голос
/ 31 декабря 2013
>>> a = numpy.random.rand(2,2)
>>> a
array([[ 0.41668355,  0.07982691], 
       [ 0.60790982,  0.0314224 ]])
>>> a - numpy.diag(numpy.diag(a))
array([[ 0.        ,  0.07982691],
       [ 0.60790982,  0.        ]])
1 голос
/ 31 марта 2012
def replaceDiagonal(matrix, replacementList):
    for i in range(len(replacementList)):
        matrix[i][i] = replacementList[i]

Где размер n в матрице n x n.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...