2017-04-09 92 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) 
你做