2012-05-29 101 views
13

我正試圖在numpy中生成對稱矩陣。具體而言,這些矩陣將具有隨機地點條目,並且在每個條目中,內容可以是隨機的。沿着主對角線,我們不關心那裏有什麼內容,所以我也隨機化了這些內容。在Numpy中生成對稱矩陣

我採取的方法是首先生成一個nxn全零矩陣,並簡單地遍歷矩陣的索引。然而,考慮到循環在python中相對昂貴,我想知道如果我可以在不使用python for循環的情況下實現同樣的功能。

是否有一些內置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 

回答

18

你可能只是這樣做:

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

裏面有多個內置例程來構建圖:

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

此外,如果你想添加一些隨機放置的零的數量,你總是可以生成一組隨機的指數並用零代替這些值。

+0

謝謝!這是一個有效的解決方案。但是,有什麼方法可以讓它隨機放置零點?這個矩陣應該表示圖的一種鄰接矩陣,所以有一個隨機分佈零的矩陣是比較好的。 – Ryan

+4

@Ryan:你關心隨機條目有什麼樣的分佈?如果你添加'b + b.T',你會得到一個非均勻分佈,集中在0. – unutbu

+0

我正在驗證矩陣的一些屬性。它更努力提供一些數學性質的令人信服的證據,因此這裏的分佈並不重要。雖然謝謝! – Ryan

13

我最好再做:

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

,因爲在這種情況下,矩陣的所有元素都來自相同的分佈(統一在這種情況下)。

+0

這是保持相同分佈的非常優雅的方式! – Arash

0

如果你不介意,你可以使用下面的代碼片段對角線具有零:

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 

請注意,您只需要生成N *(N-1)/ 2隨機因變量對稱。

0

我使用下面的函數,使矩陣對稱的垂直和水平:

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]])