使用numpy改变矩阵的形状

时间:2017-04-09 12:35:18

标签: python numpy matrix

我的问题是双重的。我有以下代码可以处理一些矩阵。

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)如何重塑&new;是320乘320?

4 个答案:

答案 0 :(得分: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部分。没有必要重塑newMatrix,因为它已经是(320,320)。

让我们回到你的问题的A部分“为什么newMatrix newMatrix = newMatrix[matrix]变为320x320x320后会发生这种情况?

答案是:因为使用newMatrix[matrix]完全应该做的事情,所以创建一个320x320x320矩阵。

答案 1 :(得分:0)

对于您的第一个问题A),我建议您阅读this (Index arrays)

索引数组的使用有时可能不直观,因此请参阅以下矩阵索引:

import numpy as np

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

我们得到:

[ 1.  0.]

结果是沿最大维度(dim 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。

在您的示例中,您的最终newMatrixmatrix类似,但matrix中的每个标量都被初始newMatrix的第0行或第1行替换,从而给出结果的最终形状。

但这可能不是你想要的。看一下布尔索引可能会很有趣。我建议阅读this (Boolean or “mask” index arrays)

答案 2 :(得分: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)

答案 3 :(得分: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]]])

mask更改为布尔值会生成1d数组,从arr中选择与Truemask的位置匹配的值:

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)