Генерация симметричных матриц в пакете numpy
Я пытаюсь генерировать симметричные матрицы в numpy. В частности, эти матрицы должны иметь случайные места записей, и в каждой записи содержимое может быть случайным. Вдоль главной диагонали нас не интересует, какие энты там находятся, поэтому я произвел рандомизацию и их.
Подход, который я использовал, заключается в том, чтобы сначала сгенерировать матрицу NxN all zero и просто замкнуть цикл над индексами матриц. Однако, учитывая, что циклирование относительно дорого в 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
4 ответов:
Вы можете просто сделать что-то вроде:
import numpy as np N = 100 b = np.random.random_integers(-2000,2000,size=(N,N)) b_symm = (b + b.T)/2Где вы можете выбрать из любого распределения, которое вы хотите в
np.randomили эквивалентном модуле scipy.Обновление: Если вы пытаетесь построить графоподобные структуры, обязательно проверьте пакет networkx:
Который имеет ряд встроенных подпрограмм для построения графиков:
Http://networkx.lanl.gov/reference/generators.html
Также, если вы хотите чтобы добавить некоторое количество случайно расположенных нулей, вы всегда можете сгенерировать случайный набор индексов и заменить значения нулем.
Я лучше сделаю:
Потому что в этом случае все элементы матрицы находятся из одного и того же распределения (равномерного в данном случае).a = np.random.rand(N, N) m = np.tril(a) + np.tril(a, -1).T
Если вы не возражаете иметь нули на диагонали, вы можете использовать следующий фрагмент:
Обратите внимание, что вам нужно только генерировать N*(n-1)/2 случайных переменных из-за симметрии.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)] = P.T[np.tril_indices(n, -1)] return P
Я использую следующую функцию, чтобы сделать матрицу симметричной как по вертикали, так и по горизонтали:
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]])
Comments