Nếu bạn có thể đủ khả năng để làm cho cân đối các ma trận ngay trước khi làm phép tính, sau đây nên được hợp lý nhanh:
def symmetrize(a):
return a + a.T - numpy.diag(a.diagonal())
này hoạt động theo các giả định hợp lý (chẳng hạn như không làm cả hai a[0, 1] = 42
và mâu thuẫn a[1, 0] = 123
trước khi chạy symmetrize
).
Nếu bạn thực sự cần một symmetrization trong suốt, bạn có thể xem xét subclassing numpy.ndarray và chỉ cần xác định lại __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!
(hoặc tương đương với ma trận thay vì mảng, tùy thuộc vào nhu cầu của bạn). Cách tiếp cận này thậm chí còn xử lý các bài tập phức tạp hơn, chẳng hạn như a[:, 1] = -1
, cách đặt chính xác các yếu tố a[1, :]
.
Lưu ý rằng Python 3 loại bỏ khả năng viết def …(…, (i, j),…)
, vì vậy các mã có được một chút thích nghi trước khi chạy với Python 3: def __setitem__(self, indexes, value): (i, j) = indexes
...
Bạn có thể xem xét đánh dấu câu trả lời như chấp nhận, nếu nó giải quyết vấn đề của bạn. :) – EOL
Tôi muốn đợi câu trả lời tốt hơn (tức là được tích hợp sẵn và bộ nhớ hiệu quả). Không có gì sai với câu trả lời của bạn, tất nhiên, vì vậy tôi sẽ chấp nhận nó. – Debilski