Numpy изменить диагональ ndarray - PullRequest
13 голосов
/ 13 сентября 2011

есть ли способ в numpy получить ссылку на диагональ массива?Я хочу, чтобы диагональ моего массива была поделена на определенный коэффициент. Спасибо

Ответы [ 4 ]

19 голосов
/ 13 сентября 2011

Если X является вашим массивом, а c является фактором,

X[np.diag_indices_from(X)] /= c

См. diag_indices_from в руководстве Numpy.

17 голосов
/ 05 мая 2012

Быстрый способ получить доступ к диагонали квадрата (n,n) массив numpy с помощью arr.flat[::n+1]:

n = 1000
c = 20
a = np.random.rand(n,n)

a[np.diag_indices_from(a)] /= c # 119 microseconds
a.flat[::n+1] /= c # 25.3 microseconds
7 голосов
/ 18 февраля 2014

Функция np.fill_diagonal довольно быстрая:

np.fill_diagonal(a, a.diagonal() / c)

, где a - ваш массив, а c - ваш фактор.На моей машине этот метод был таким же быстрым, как метод a.flat[::n+1] /= c @ kwgoodman, и, на мой взгляд, немного более четким (но не таким гладким).

6 голосов
/ 29 марта 2016

Сравнение вышеуказанных 3 методов:

import numpy as np
import timeit

n = 1000
c = 20
a = np.random.rand(n,n)
a1 = a.copy()
a2 = a.copy()
a3 = a.copy()

t1 = np.zeros(1000)
t2 = np.zeros(1000)
t3 = np.zeros(1000)

for i in range(1000):
    start = timeit.default_timer()
    a1[np.diag_indices_from(a1)] /= c 
    stop = timeit.default_timer()
    t1[i] = start-stop

    start = timeit.default_timer()
    a2.flat[::n+1] /= c
    stop = timeit.default_timer()
    t2[i] = start-stop

    start = timeit.default_timer()
    np.fill_diagonal(a3,a3.diagonal() / c)
    stop = timeit.default_timer()
    t3[i] = start-stop

print([t1.mean(), t1.std()])
print([t2.mean(), t2.std()])
print([t3.mean(), t3.std()])

[-4.5693619907979154e-05, 9.3142851395411316e-06]
[-2.338075107036275e-05, 6.7119609571872443e-06]
[-2.3731951987429056e-05, 8.0455946813059586e-06]

Итак, вы можете видеть, что метод np.flat самый быстрый, но незначительный. Когда я запускал это еще несколько раз, были случаи, когда метод fill_diagonal был немного быстрее. Но для удобства чтения, вероятно, стоит использовать метод fill_diagonal.

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