2017-04-09 90 views
0

我的問題是雙重的。我有下面的代碼來處理一些矩陣。使用numpy更改矩陣的形狀

import numpy 
tupleList = [(0, 122), (1, 246), (2, 157), (3, 166), (4, 315), (5, 108), (6, 172), (7, 20), (8, 173), (9, 38), (10, 28), (11, 72), (12, 102), (13, 277), (14, 318), (15, 316), (16, 283), (17, 31), (18, 160), (19, 97), (20, 26), (21, 252), (22, 105), (23, 133), (24, 162), (25, 116), (26, 284), (27, 25), (28, 80), (29, 225), (30, 107), (31, 111), (32, 208), (33, 121), (34, 249), (35, 314), (36, 163), (37, 170), (38, 48), (39, 142), (40, 95), (41, 113), (42, 285), (43, 88), (44, 184), (45, 63), (46, 129), (47, 137), (48, 87), (49, 135), (50, 207), (51, 276), (52, 174), (53, 143), (54, 92), (55, 313), (56, 85), (57, 185), (58, 96), (59, 86), (60, 222), (61, 274), (62, 0), (63, 256), (64, 27), (65, 81), (66, 219), (67, 271), (68, 115), (69, 212), (70, 83), (71, 302), (72, 69), (73, 211), (74, 139), (75, 110), (76, 2), (77, 298), (78, 244), (79, 299), (80, 248), (81, 57), (82, 293), (83, 241), (84, 188), (85, 250), (86, 29), (87, 149), (88, 51), (89, 75), (90, 264), (91, 59), (92, 33), (93, 10), (94, 210), (95, 90), (96, 262), (97, 73), (98, 138), (99, 74), (100, 89), (101, 124), (102, 118), (103, 112), (104, 295), (105, 56), (106, 100), (107, 305), (108, 273), (109, 220), (110, 66), (111, 218), (112, 141), (113, 267), (114, 47), (115, 61), (116, 224), (117, 123), (118, 136), (119, 127), (120, 126), (121, 125), (122, 292), (123, 64), (124, 84), (125, 18), (126, 134), (127, 24), (128, 279), (129, 13), (130, 1), (131, 6), (132, 282), (133, 290), (134, 151), (135, 245), (136, 307), (137, 257), (138, 187), (139, 148), (140, 234), (141, 158), (142, 161), (143, 268), (144, 209), (145, 140), (146, 35), (147, 8), (148, 291), (149, 177), (150, 7), (151, 11), (152, 194), (153, 9), (154, 195), (155, 82), (156, 186), (157, 270), (158, 280), (159, 104), (160, 101), (161, 98), (162, 50), (163, 99), (164, 216), (165, 117), (166, 215), (167, 62), (168, 297), (169, 39), (170, 176), (171, 150), (172, 60), (173, 197), (174, 183), (175, 237), (176, 192), (177, 189), (178, 23), (179, 303), (180, 272), (181, 213), (182, 37), (183, 217), (184, 236), (185, 147), (186, 199), (187, 41), (188, 55), (189, 175), (190, 67), (191, 193), (192, 46), (193, 196), (194, 278), (195, 251), (196, 204), (197, 53), (198, 258), (199, 179), (200, 247), (201, 260), (202, 238), (203, 159), (204, 114), (205, 223), (206, 308), (207, 243), (208, 45), (209, 52), (210, 269), (211, 152), (212, 154), (213, 146), (214, 198), (215, 190), (216, 203), (217, 319), (218, 242), (219, 294), (220, 130), (221, 68), (222, 311), (223, 155), (224, 36), (225, 281), (226, 17), (227, 310), (228, 296), (229, 12), (230, 153), (231, 120), (232, 4), (233, 65), (234, 180), (235, 202), (236, 226), (237, 54), (238, 289), (239, 254), (240, 109), (241, 144), (242, 205), (243, 132), (244, 240), (245, 178), (246, 263), (247, 232), (248, 58), (249, 214), (250, 275), (251, 306), (252, 309), (253, 181), (254, 231), (255, 103), (256, 227), (257, 165), (258, 286), (259, 171), (260, 32), (261, 70), (262, 312), (263, 301), (264, 287), (265, 288), (266, 206), (267, 230), (268, 16), (269, 91), (270, 182), (271, 43), (272, 191), (273, 228), (274, 317), (275, 265), (276, 145), (277, 239), (278, 259), (279, 167), (280, 34), (281, 106), (282, 131), (283, 76), (284, 266), (285, 49), (286, 300), (287, 201), (288, 93), (289, 44), (290, 42), (291, 40), (292, 3), (293, 229), (294, 304), (295, 14), (296, 94), (297, 261), (298, 221), (299, 168), (300, 255), (301, 156), (302, 233), (303, 253), (304, 77), (305, 235), (306, 79), (307, 15), (308, 19), (309, 119), (310, 78), (311, 200), (312, 5), (313, 169), (314, 128), (315, 21), (316, 22), (317, 164), (318, 30), (319, 71)] 
var = 320 
def binaryMatrix(list): 
    size = len(list) 
    matrix = numpy.zeros((size,size)) 
    for tuple in list: 
     matrix[tuple[0],tuple[1]] = 1 
    #for row in matrix: 
    # print sum(row) 
    # if sum(row) > 1: 
    #  print "Incorrect" 
    #  break 
    #print matrix 
return matrix 


matrix = binaryMatrix(tupleList) 
matrix = numpy.asarray(matrix,int) 
newMatrix = numpy.eye(var) 
#print newMatrix 
print numpy.shape(newMatrix) 
newMatrix = newMatrix[matrix] 
print newMatrix 
print numpy.shape(newMatrix) 

該函數採用一個元組列表,並構造正方形二進制矩陣,其中在每個元組的位置處的條目是1,並且所有其他元素爲0。註釋代碼是簡單地確保所有的行總和爲1,他們這樣做,所以它是一個有效的二進制矩陣。

我遇到的問題是在這一行:newMatrix = newMatrix [matrix] 當打印形狀後,我得到它的尺寸是320 * 320 * 320;但我正在尋找的是320 * 320。

有人可以向我解釋A)爲什麼會發生這種情況,以及B)如何重塑'newMatrix'爲320乘320?

+0

'打印(numpy.shape(newMatrix))'前'newMatrix = newMatrix [matrix]給出(320,320)...嗯......你想用'newMatrix = newMatrix [matrix]'完成什麼? newMatrix已經有了你想要的形狀,因爲numpy.eye(var)就是這樣創建的。 – Claudio

+0

所以答案是A)發生這種情況是因爲你使用的代碼完全是這樣的B)沒有必要將newMatrix重塑爲320x320,因爲它已經以這種方式成形。 – Claudio

+0

'newMatrix [matrix]'的用途是什麼?用矩陣索引是棘手的。先用小陣列練習。 – hpaulj

回答

0

代碼:

print("numpy.eye(320) gives a matrix of shape:" , numpy.eye(320).shape) 

給出:

numpy.eye(320) gives a matrix of shape: (320, 320) 

這個回答你的問題的B部分。因爲它已經是(320,320),所以不需要重塑newMatrix

所以,讓我們在A部分你的問題:「爲什麼會出現這種情況變得newMatrixnewMatrix = newMatrix[matrix] 320x320x320

答案是:?因爲使用newMatrix[matrix]不正是它應該做的,創建一個320x320x320矩陣

+0

你原來是完全正確的 - 事實證明我寫的代碼對於我想實現的目標完全錯誤。二進制矩陣實際上就是我所需要的,我之後所做的一切都是多餘的。 感謝您的幫助,不管!我將把這個問題標記爲答案。 – modestmotion

0

爲了您的第一個問題),我建議你閱讀this (Index arrays)

使用數組索引有時可以是非直觀的,故見例如下面的矩陣索引:

import numpy as np 

newMatrix = np.eye(2) 
print newMatrix[0] 

我們得到:

[ 1. 0.] 

結果是沿着最大尺寸的陣列的第一個元素(暗2),即,矩陣的第一行。現在,如果使用數組我們指數(注意加括號):

import numpy as np 
newMatrix = np.eye(2) 
print newMatrix[[0]] 

我們得到:

[[ 1. 0.]] 

這一次,結果還是矩陣的第一行,但在一個給定的具有與索引數組相似形狀的數組。從上方連結的頁面:

一般而言,當使用索引數組返回什麼是 陣列相同的形狀的索引數組,但與該類型和陣列的 值被編入索引。

所以我想numpy用索引標量給出的矩陣元素替換索引數組中的標量。如果我們嘗試索引一個矩陣:

import numpy as np 

indx = np.array([[1,0],[0,1]]) 
newMatrix = np.eye(2) 
print newMatrix[indx] 

給我們:

[[[ 0. 1.] 
    [ 1. 0.]] 

[[ 1. 0.] 
    [ 0. 1.]]] 

因爲索引陣列中的每個標量是通過在結果矩陣的相應行更換,從而也增加了維度與索引數組相比1的結果。

在您的例子,最終newMatrix是類似於您matrix,但是其中在每matrix標量由初始newMatrix的任行0或1代替,從而使你的結果的最終形狀。

雖然這可能不是你想要的。查看布爾索引可能會很有趣。我建議您閱讀this (Boolean or 「mask」 index arrays)

0

您可以爲自己節省大量的工作,如果你讓與NumPy做索引:

# Wrap indices in numpy array 
idxarray = numpy.array(tupleList) 

# Allocate zeros 
data = numpy.zeros((320, 320)) 

# Set positions in `tupleList` to `1` 
data[idxarray[:, 0], idxarray[:, 1]] = 1 

# Make sure we only have one `1` per row 
print numpy.all(numpy.sum(data, axis=0) <= 1) # True 

# Make sure our shape is correct 
print data.shape # (320, 320) 
+0

但是他的問題出現在創建這個nxn數組之後。 – hpaulj

+0

我不確定OP是否真的知道他想要完成什麼... –

0

讓我們實驗用小型3x3的陣列:

In [25]: mask = np.array([[1,0,0],[0,0,1],[0,1,0]]) 
In [26]: mask 
Out[26]: 
array([[1, 0, 0], 
     [0, 0, 1], 
     [0, 1, 0]]) 
In [27]: arr = np.arange(9).reshape(3,3) 
In [28]: arr 
Out[28]: 
array([[0, 1, 2], 
     [3, 4, 5], 
     [6, 7, 8]]) 

使用mask爲你做產生(3,3,3)陣列:

In [29]: arr[mask] 
Out[29]: 
array([[[3, 4, 5], 
     [0, 1, 2], 
     [0, 1, 2]], 

     [[0, 1, 2], 
     [0, 1, 2], 
     [3, 4, 5]], 

     [[0, 1, 2], 
     [3, 4, 5], 
     [0, 1, 2]]]) 

Cha nging mask到布爾值,產生一維數組,選擇從arrmask匹配True位置該值:

In [30]: arr[mask.astype(bool)] 
Out[30]: array([0, 5, 7]) 

另一種選擇是乘法,這將零輸出值,返回一個(3,3):

In [31]: arr*mask 
Out[31]: 
array([[0, 0, 0], 
     [0, 0, 5], 
     [0, 7, 0]]) 

或遮蓋陣列類似的東西:

In [37]: np.ma.MaskedArray(arr,~mask.astype(bool)) 
Out[37]: 
masked_array(data = 
[[0 -- --] 
[-- -- 5] 
[-- 7 --]], 
      mask = 
[[False True True] 
[ True True False] 
[ True False True]], 
     fill_value = 999999) 
你做