Создание симметричных матриц в Numpy

Я пытаюсь создать симметричные матрицы в numpy. В частности, эти матрицы должны иметь записи случайных мест, и в каждой записи содержимое может быть случайным. Вдоль главной диагонали нас не волнует то, что там есть, поэтому я тоже их рандомизировал.

Подход, который я принял, состоит в том, чтобы сначала сгенерировать nxn всю нулевую матрицу и просто петлю по индексам матриц. Однако, учитывая, что рассмотрение цикла является относительно дорогостоящим в python, мне интересно, могу ли я получить то же самое без использования петель python.

Есть ли какие-то вещи, встроенные в numpy, которые позволяют мне более эффективно выполнять мою задачу?

Вот мой текущий код:

import numpy as np import random def empty(x, y): return x*0 b = np.fromfunction(empty, (n, n), dtype = int) for i in range(0, n): for j in range(0, n): if i == j: b[i][j] = random.randrange(-2000, 2000) else: switch = random.random() random.seed() if switch > random.random(): a = random.randrange(-2000, 2000) b[i][j] = a b[j][i] = a else: b[i][j] = 0 b[j][i] = 0 

Вы могли бы просто сделать что-то вроде:

 import numpy as np N = 100 b = np.random.random_integers(-2000,2000,size=(N,N)) b_symm = (b + bT)/2 

Где вы можете выбрать любой дистрибутив в np.random или эквивалентном модуле scipy.

Обновление: если вы пытаетесь построить графические структуры, обязательно проверьте пакет networkx:

http://networkx.lanl.gov

который имеет ряд встроенных подпрограмм для построения графиков:

http://networkx.lanl.gov/reference/generators.html

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

Мне лучше:

 a = np.random.rand(N, N) m = np.tril(a) + np.tril(a, -1).T 

потому что в этом случае все элементы матрицы из одного и того же распределения (однородные в этом случае).

Если вы не против иметь нули по диагонали, вы можете использовать следующий фрагмент:

 def random_symmetric_matrix(n): _R = np.random.uniform(-1,1,n*(n-1)/2) P = np.zeros((n,n)) P[np.triu_indices(n, 1)] = _R P[np.tril_indices(n, -1)] = PT[np.tril_indices(n, -1)] return P 

Обратите внимание, что вам нужно только генерировать n * (n-1) / 2 случайные величины из-за симметрии.

Я использую следующую функцию, чтобы сделать матрицу симметричной как по вертикали, так и по горизонтали:

 def make_sym(a): w, h = a.shape a[w - w // 2 :, :] = np.flipud(a[:w // 2, :]) a[:, h - h // 2:] = np.fliplr(a[:, :h // 2]) 

Позвольте проверить, как это работает:

 >>> m = (np.random.rand(10, 10) * 10).astype(np.int) >>> make_sym(m) >>> m array([[2, 7, 5, 7, 7, 7, 7, 5, 7, 2], [6, 3, 9, 3, 6, 6, 3, 9, 3, 6], [1, 4, 6, 7, 2, 2, 7, 6, 4, 1], [9, 2, 7, 0, 8, 8, 0, 7, 2, 9], [5, 5, 6, 1, 9, 9, 1, 6, 5, 5], [5, 5, 6, 1, 9, 9, 1, 6, 5, 5], [9, 2, 7, 0, 8, 8, 0, 7, 2, 9], [1, 4, 6, 7, 2, 2, 7, 6, 4, 1], [6, 3, 9, 3, 6, 6, 3, 9, 3, 6], [2, 7, 5, 7, 7, 7, 7, 5, 7, 2]])