как изменить значения диагонали матрицы в numpy?
Я проверил Numpy изменить диагональ ndarray, но функция там не реализована в numpy v 1.3.0.
позволяет сказать, что у нас есть np.array X, и я хочу установить все значения диагонали на 0.
как изменить значения диагонали матрицы в numpy?
Я проверил Numpy изменить диагональ ndarray, но функция там не реализована в numpy v 1.3.0.
позволяет сказать, что у нас есть np.array X, и я хочу установить все значения диагонали на 0.
Вы попробовали numpy.fill_diagonal
? См. Следующий ответ и этот discussion. Или из документации (хотя в настоящее время не работает):
http://docs.scipy.org/doc/numpy/reference/generated/numpy.fill_diagonal.html
Если вы используете версию 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
возвращает итератор.)
Вот еще один хороший способ сделать это. Если вы хотите, чтобы одномерный вид основной диагонали массива использовал:
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
Minimal. Код.
X[np.diag_indices_from(X)] = 0.
def replaceDiagonal(matrix, replacementList):
for i in range(len(replacementList)):
matrix[i][i] = replacementList[i]
Где размер n в n x n-матрице.
>>> 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. ]])
Вы можете сделать следующее.
Предполагая, что ваша матрица имеет матрицу 4 * 4.
indices_diagonal = np.diag_indices(4)
yourarray[indices_diagonal] = Val