Jeśli możesz sobie pozwolić na symetryzować matrycę tylko przed wykonaniem obliczeń, następujące dokumenty powinny być w miarę szybko:
def symmetrize(a):
return a + a.T - numpy.diag(a.diagonal())
Działa to na rozsądnych założeniach (jak nie robi zarówno a[0, 1] = 42
i sprzeczne a[1, 0] = 123
przed uruchomieniem symmetrize
).
Jeśli naprawdę potrzebują przejrzystych symetryczne, można rozważyć instacji numpy.ndarray i po prostu przedefiniowanie __setitem__
:
class SymNDArray(numpy.ndarray):
def __setitem__(self, (i, j), value):
super(SymNDArray, self).__setitem__((i, j), value)
super(SymNDArray, self).__setitem__((j, i), value)
def symarray(input_array):
"""
Returns a symmetrized version of the array-like input_array.
Further assignments to the array are automatically symmetrized.
"""
return symmetrize(numpy.asarray(input_array)).view(SymNDArray)
# Example:
a = symarray(numpy.zeros((3, 3)))
a[0, 1] = 42
print a # a[1, 0] == 42 too!
(lub równowartość w matrycach zamiast tablic, w zależności od potrzeb). Takie podejście obsługuje nawet bardziej skomplikowane zadania, takie jak a[:, 1] = -1
, które poprawnie ustawia elementy a[1, :]
.
Zauważ, że Python 3 usunięto możliwość pisania def …(…, (i, j),…)
, więc kod musi być nieznacznie dostosowane przed uruchomieniem z Python 3: def __setitem__(self, indexes, value): (i, j) = indexes
...
Można rozważyć oznaczenie odpowiedzi jako przyjęte, jeśli to rozwiązuje problem. :) – EOL
Chciałem poczekać na lepszą (tj. Wbudowaną i wydajną pod względem pamięci) odpowiedź. Oczywiście nie ma w tym nic złego, więc i tak to przyjmuję. – Debilski