How to create an array from a given array of ranges - python

I have this code:
pg=[(10, 19), (30, 32), (37, 38), (50, 59), (63, 64),
(69, 69), (120, 121), (124, 129), (130, 139), (160, 161),
(164, 169), (180, 182), (185, 185), (189, 189), (190, 192),
(194, 194), (196, 199), (260, 269), (270, 279), (300, 309),
(330, 339), (358, 359), (360, 369)]
Those are given ranges, for example, pg[0] should be 10, pg[1] be 11, pg[2] be 12. and so on for the rest of the ranges. So I want the final array to be like this:
pg=[10, 11, 12, 13 ....19, 30, 31,....,32,37, 38,50,51,....,59,63.. and so on]
How can I do this in python? Is it possible to do it without hard coding every range of elements in a new array?

I guess the following might work
pg = [(10, 19), (30, 32), (37, 38), (50, 59), (63, 64),
(69, 69), (120, 121), (124, 129), (130, 139), (160, 161),
(164, 169), (180, 182), (185, 185), (189, 189), (190, 192),
(194, 194), (196, 199), (260, 269), (270, 279), (300, 309),
(330, 339), (358, 359), (360, 369)]
arr = []
for val in pg:
arr += list(range(val[0], val[1] + 1))
print(arr)

This is one approach using a list comprehension and itertools.chain(to flatten the list)
Ex:
from itertools import chain
pg=[(10, 19), (30, 32), (37, 38), (50, 59), (63, 64),
(69, 69), (120, 121), (124, 129), (130, 139), (160, 161),
(164, 169), (180, 182), (185, 185), (189, 189), (190, 192),
(194, 194), (196, 199), (260, 269), (270, 279), (300, 309),
(330, 339), (358, 359), (360, 369)]
result = list(chain.from_iterable([range(*i) for i in pg]))
print(result)

A one-linear
sum([list(range(x1, x2+1)) for x1, x2 in pg], [])

Try this
l = []
for r in pg:
l.extend(range(r[0], r[1]+1))

One more example using list comprehension
a = [(10, 19), (30, 35)]
b = [j for i in a for j in range(i[0], i[1]+1)]
print(b)
#output
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 30, 31, 32, 33, 34, 35]

with help of sum function also we can achieve this.
pg=[(10, 19), (30, 32), (37, 38), (50, 59), (63, 64),
(69, 69), (120, 121), (124, 129), (130, 139), (160, 161),
(164, 169), (180, 182), (185, 185), (189, 189), (190, 192),
(194, 194), (196, 199), (260, 269), (270, 279), (300, 309),
(330, 339), (358, 359), (360, 369)]
print (list(sum(pg,())))
#output:[10, 19, 30, 32, 37, 38, 50, 59, 63, 64, 69, 69, 120, 121, 124, 129, 130, 139,
#160, 161, 164, 169, 180, 182, 185, 185, 189, 189, 190, 192, 194, 194, 196, 199, 260,
#269, 270, 279, 300, 309, 330, 339, 358, 359, 360, 369]

Related

Changing an attribute in the init method in python

So in my snake class, I have initialized an attribute as self.x_cor = 0
Now, I want to modify or make use of this attribute in a different method (create_segment). It only works when I repeat the line of code (self.x_cor = 0 ) in the (create_segment) again.
If I don't repeat it, I get feedback that the snake object has no attribute as x_cor meanwhile I have initialized it in the init method
How do I use a different method to modify an attribute initialized in the init method?
import turtle
from turtle import Turtle
import random
MOVE_DISTANCE = 20
UP = 90
DOWN = 270
LEFT = 180
RIGHT = 0
class Snake:
def __init__(self):
self.speed = 9
self.segments = []
self.create_snake()
self.x_cor = 0
self.y_cor = 0
# self.add_segment()
self.head = self.segments[0] # the first segment is designated as the head of the snake
self.color_list = [(202, 164, 110), (240, 245, 241), (236, 239, 243), (149, 75, 50), (222, 201, 136),
(170, 154, 41), (138, 31, 20), (134, 163, 184), (197, 92, 73), (47, 121, 86), (73, 43, 35),
(145, 178, 149), (14, 98, 70), (232, 176, 165), (160, 142, 158), (54, 45, 50), (101, 75, 77),
(183, 205, 171), (36, 60, 74), (19, 86, 89), (82, 148, 129), (147, 17, 19), (27, 68, 102),
(12, 70, 64), (107, 127, 153), (176, 192, 208), (168, 99, 102), (53, 93, 123)]
self.colors = ["red", "orange", "yellow", "blue", "green", "purple"]
def create_snake(self):
""" Creates the snake """
for n in range(3): # Creates 3 segments for now
self.create_segment(n)
def create_segment(self, n):
""" Creates a new segment to be added to the snake """
new_segment = Turtle("square")
turtle.colormode(255)
self.color_list = [(202, 164, 110), (240, 245, 241), (236, 239, 243), (149, 75, 50), (222, 201, 136),
(170, 154, 41), (138, 31, 20), (134, 163, 184), (197, 92, 73), (47, 121, 86), (73, 43, 35),
(145, 178, 149), (14, 98, 70), (232, 176, 165), (160, 142, 158), (54, 45, 50), (101, 75, 77),
(183, 205, 171), (36, 60, 74), (19, 86, 89), (82, 148, 129), (147, 17, 19), (27, 68, 102),
(12, 70, 64), (107, 127, 153), (176, 192, 208), (168, 99, 102), (53, 93, 123)]
# new_segment.color(random.choice(self.color_list))
self.colors = ["red", "orange", "yellow", "blue", "green", "purple"]
new_segment.color(random.choice(self.colors))
new_segment.penup()
# new_segment.speed(9)
self.x_cor = 0
self.y_cor = 0
new_segment.goto(self.x_cor, self.y_cor)
self.x_cor -= 20 # Reduce the x_cor but maintain the y so all the segments will be on the same horizontal
# but different vertical axis
self.segments.append(new_segment)
if I don't repeat
self.x_cor = 0
self.y_cor = 0
in the 2nd method, I get feedback as "line 49, in create_segment
new_segment.goto(self.x_cor, self.y_cor)
AttributeError: 'Snake' object has no attribute 'x_cor'. Did you mean: 'y_cor'?
I really think repetition is not necessary but how do I avoid that?
Thank you very much
In the create_snake in your constructor you are basically trying to access self.x_cor before it is created, because create_snake calls create_segment that refers to self.x_cor before it is initialized.

Problem with superpixel segmentation (opencv in python) - holes in contours of the segmentation mask

I am trying superpixel segmentation with OpenCV in Python. I have tried implementing LSC, SLIC and SEEDS algorithms https://docs.opencv.org/3.4/df/d6c/group__ximgproc__superpixel.html in order to segment cell nuclei, however, so far only SEEDS algorithm works. Countours in segmentation masks created via .getLabelContourMask() method contained holes for both LSC and SLIC algorithms, which led to flooding of the whole (LSC) or large portion (SLIC) of the mask when using floodfill() method https://docs.opencv.org/3.4/d7/d1b/group__imgproc__misc.html. The trend is - the better the segmentation (eg the lower the ratio value in LSC), the leakier the contours in the mask (which I am assuming should not happen). Only SEEDS worked as expected - no apparent holes/openings in contours of the mask, thus only areas around seedpoints flooded after using floodfill(). Anyone had the same experience? Any idea why this might be the case (may OpenCV implementation of LSC and SLIC be problematic?)? Can anything be done to close the contours/edges in the LSC/SLIC mask? Newbie in comp sci over here, any help appreciated.
Test Code for LSC:
lsc = cv2.ximgproc.createSuperpixelLSC(image, region_size=25, ratio=0.1)
lsc.iterate(100)
lsc_mask = lsc.getLabelContourMask()
cv2.imwrite("lsc_mask.tif", lsc_mask) #holes visible when zooming in
x, y = lsc_mask.shape
m = np.zeros((x+2, y+2),dtype=np.uint8)
for point in nuclei_coordinates:
retval, lsc_mask_flooded, m_flooded, rect = cv2.floodFill(image=lsc_mask, mask=m, seedPoint=point, newVal=(255,255,255), loDiff=0, upDiff=0)
cv2.imwrite("lsc_mask_flooded.tif", lsc_mask_flooded) #almost whole image flooded
cv2.imwrite("m_flooded.tif", m_flooded*255)
original image (.tif)
lsc_mask for the image (.tif)
lsc_mask zoomed in
image - lsc_mask overlay (.tif)
lsc_mask_flooded (.tif)
m_flooded (.tif)
nuclei_coordinates = [(56, 106), (32, 116), (13, 125), (18, 145), (32, 147), (13, 160), (10, 182), (46, 192), (39, 208), (33, 227), (14, 231), (27, 255), (31, 272), (38, 284), (45, 301), (82, 312), (70, 252), (56, 261), (51, 244), (63, 219), (103, 334), (121, 334), (131, 316), (148, 322), (170, 295), (219, 261), (224, 227), (220, 180), (192, 178), (196, 162), (211, 157), (215, 138), (207, 116), (190, 109), (192, 97), (186, 81), (170, 73), (174, 106), (158, 115), (147, 130), (152, 168), (156, 195), (173, 189), (131, 205), (148, 59), (125, 84), (134, 105), (150, 101), (119, 102), (124, 124), (141, 147), (122, 167), (103, 168), (112, 188), (78, 202), (104, 206), (102, 229), (116, 228), (134, 221), (146, 221), (81, 177), (110, 153), (116, 148), (111, 140), (100, 144), (91, 130), (88, 146), (74, 142), (79, 155), (54, 137), (71, 125), (82, 100), (72, 96), (76, 77), (95, 70), (104, 60), (198, 292), (207, 276), (162, 309), (148, 292), (148, 305), (131, 283), (100, 298), (232, 15), (212, 24), (225, 42), (215, 68), (247, 83), (238, 57), (264, 54), (282, 44), (317, 27), (318, 11), (309, 68), (319, 56), (306, 97), (297, 91), (233, 117), (309, 127), (314, 139), (319, 165), (326, 176), (339, 197), (350, 214), (351, 240), (364, 253), (366, 279), (378, 300), (355, 308), (332, 298), (310, 296), (314, 271), (336, 273), (283, 279), (271, 285), (258, 270), (264, 256), (250, 260), (259, 246), (245, 228), (247, 211), (255, 163), (280, 162), (293, 148), (370, 452), (368, 421), (358, 399), (358, 380), (339, 358), (337, 397), (342, 373), (328, 338), (336, 466), (325, 452), (338, 431), (324, 433), (306, 421), (317, 412), (324, 387), (323, 370), (313, 356), (298, 388), (289, 428), (265, 454), (244, 450), (241, 432), (269, 426), (275, 397), (303, 337), (283, 344), (278, 323), (264, 332), (270, 345), (242, 352), (218, 369), (225, 345), (219, 332), (208, 316), (190, 327), (183, 342), (171, 347), (136, 369), (134, 386), (152, 400), (130, 411), (154, 454), (147, 431), (183, 443), (208, 440), (194, 422), (183, 403), (232, 414), (215, 466), (296, 468), (452, 8), (464, 24), (480, 43), (431, 41), (445, 34), (427, 23), (406, 12), (380, 17), (373, 34), (351, 33), (389, 42), (409, 38), (421, 54), (414, 78), (395, 79), (403, 59), (378, 83), (363, 85), (345, 91), (342, 66), (349, 53), (375, 55), (489, 58), (492, 37), (511, 49), (536, 48), (540, 66), (544, 84), (547, 101), (548, 120), (529, 96), (520, 124), (540, 134), (554, 147), (500, 115), (482, 111), (471, 85), (459, 67), (448, 86), (449, 117), (442, 140), (427, 133), (418, 153), (405, 117), (358, 125), (355, 110), (341, 121), (353, 146), (371, 154), (387, 151), (394, 135), (384, 190), (384, 166), (368, 175), (368, 203), (383, 217), (394, 203), (389, 232), (404, 238), (409, 262), (419, 250), (419, 232), (450, 279), (456, 265), (476, 257), (433, 262), (435, 226), (451, 242), (424, 181), (320, 221), (443, 194), (455, 179), (474, 198), (488, 186), (504, 197), (475, 176), (555, 170), (551, 190), (532, 187), (527, 198), (504, 209), (481, 227), (468, 224), (456, 228), (556, 213), (539, 216), (536, 235), (520, 235), (492, 313), (509, 321), (488, 296), (491, 340), (508, 359), (501, 387), (490, 374), (480, 398), (475, 379), (470, 353), (452, 367), (449, 395), (436, 412), (431, 430), (461, 417), (447, 455), (468, 454), (488, 433), (428, 452), (419, 464), (505, 424), (493, 415), (519, 414), (539, 390), (547, 367), (522, 367), (543, 333), (518, 348), (556, 315), (569, 294), (643, 314), (628, 321), (623, 304), (611, 305), (595, 307), (669, 347), (673, 289), (661, 272), (632, 247), (630, 231), (621, 211), (608, 224), (611, 201), (605, 175), (635, 188), (644, 202), (662, 248), (688, 254), (713, 270), (729, 286), (720, 309), (739, 340), (733, 351), (724, 341), (736, 251), (729, 228), (724, 239), (714, 249), (711, 229), (699, 241), (680, 236), (675, 220), (695, 206), (727, 212), (734, 198), (737, 178), (720, 181), (709, 162), (738, 158), (739, 140), (721, 147), (702, 141), (681, 149), (662, 168), (663, 189), (675, 200), (658, 151), (652, 131), (667, 122), (648, 152), (617, 148), (619, 125), (583, 125), (581, 148), (574, 106), (573, 87), (576, 74), (711, 10), (725, 12), (736, 47), (724, 63), (733, 70), (713, 82), (710, 100), (696, 72), (691, 47), (691, 23), (677, 9), (694, 4), (649, 18), (654, 3), (635, 8), (622, 38), (612, 26), (598, 47), (619, 77), (630, 105), (653, 102), (640, 90), (676, 91), (661, 66), (670, 35), (703, 367), (712, 387), (684, 358), (656, 362), (626, 363), (611, 358), (600, 452), (633, 454), (574, 440), (589, 421), (580, 463), (335, 236), (721, 459), (733, 445), (717, 444), (728, 421), (740, 430), (718, 30), (584, 48), (589, 198)]
I think that the idea behind using LSC or LIS is to use it with watershed algorithm. That way you can get an image that has visible and continous segments contours.
Java code example:
SuperpixelLSC superpixelLSC = Ximgproc.createSuperpixelLSC(src, region_size);
superPixelLSC.iterate();
superPixelLSC.getLabels(markers);
Imgproc.watershed(src, markers);
You can then detect the contours on watershed algorithm results.
Had the same problem, when working with the SLIC-Segmentation. Used a dilate function after getting the mask, to fill the gaps on the lines:
dst = cv2.dilate(lsc_mask , kernel)
The dilation is a basic morphologic function to expand the boudries of a figure.
The kernel is the matrix you expand the boudries with. You can control the expansion of the boundries with the size of the kernel.
If you need more info I can suggest R.Gonzales' book-Digital Image Processing.
Here is also a quite good example with code:
https://cvexplained.wordpress.com/2020/05/18/dilation/

Find distance for every edge and keep separate routes

[[0, 100, 7, 27, 34, 40, 41, 48, 58, 65, 75, 78, 79, 96, 126, 127, 0],
[0, 2, 45, 54, 56, 57, 59, 66, 67, 82, 86, 102, 124, 133, 0],
[0, 35, 39, 52, 53, 60, 61, 80, 81, 83, 87, 97, 98, 101, 109, 0],
[0, 15, 28, 29, 30, 31, 32, 33, 37, 38, 49, 50, 51, 71, 95, 0],
[0, 3, 16, 22, 23, 44, 72, 73, 74, 90, 110, 131, 0],
[0, 10, 11, 18, 19, 36, 55, 89, 93, 94, 108, 113, 114, 0],
[0, 1, 5, 6, 9, 12, 17, 24, 43, 64, 77, 85, 88, 91, 92, 111, 112, 130, 0],
[0, 13, 20, 42, 62, 68, 84, 99, 104, 116, 119, 125, 128, 129, 132, 0],
[0, 8, 14, 26, 63, 69, 70, 103, 105, 123, 0],
[0, 4, 21, 25, 46, 47, 106, 107, 115, 117, 118, 120, 121, 122, 0],
[0, 76, 0]]
I have the different routes listed above. I need to calculate the distance of every route (11 routes in total)
After this, I have created all edges within a single route.
[[(0, 100),
(100, 7),
(7, 27),
(27, 34),
(34, 40),
(40, 41),
(41, 48),
(48, 58),
(58, 65),
(65, 75),
(75, 78),
(78, 79),
(79, 96),
(96, 126),
(126, 127),
(127, 0)],
[(0, 2),
(2, 45),
(45, 54),
(54, 56),
(56, 57),
(57, 59),
(59, 66),
(66, 67),
(67, 82),
(82, 86),
(86, 102),
(102, 124),
(124, 133),
(133, 0)],
[(0, 35),
(35, 39),
(39, 52),
(52, 53),
(53, 60),
(60, 61),
(61, 80),
(80, 81),
(81, 83),
(83, 87),
(87, 97),
(97, 98),
(98, 101),
(101, 109),
(109, 0)],
[(0, 15),
(15, 28),
(28, 29),
(29, 30),
(30, 31),
(31, 32),
(32, 33),
(33, 37),
(37, 38),
(38, 49),
(49, 50),
(50, 51),
(51, 71),
(71, 95),
(95, 0)],
[(0, 3),
(3, 16),
(16, 22),
(22, 23),
(23, 44),
(44, 72),
(72, 73),
(73, 74),
(74, 90),
(90, 110),
(110, 131),
(131, 0)],
[(0, 10),
(10, 11),
(11, 18),
(18, 19),
(19, 36),
(36, 55),
(55, 89),
(89, 93),
(93, 94),
(94, 108),
(108, 113),
(113, 114),
(114, 0)],
[(0, 1),
(1, 5),
(5, 6),
(6, 9),
(9, 12),
(12, 17),
(17, 24),
(24, 43),
(43, 64),
(64, 77),
(77, 85),
(85, 88),
(88, 91),
(91, 92),
(92, 111),
(111, 112),
(112, 130),
(130, 0)],
[(0, 13),
(13, 20),
(20, 42),
(42, 62),
(62, 68),
(68, 84),
(84, 99),
(99, 104),
(104, 116),
(116, 119),
(119, 125),
(125, 128),
(128, 129),
(129, 132),
(132, 0)],
[(0, 8),
(8, 14),
(14, 26),
(26, 63),
(63, 69),
(69, 70),
(70, 103),
(103, 105),
(105, 123),
(123, 0)],
[(0, 4),
(4, 21),
(21, 25),
(25, 46),
(46, 47),
(47, 106),
(106, 107),
(107, 115),
(115, 117),
(117, 118),
(118, 120),
(120, 121),
(121, 122),
(122, 0)],
[(0, 76), (76, 0)]]
However, I need to calculate the distance between the edges. Every edge consists of 2 numbers which are city numbers in a distance matrix (so 0,100 is the distance from city 0 to city 100). I tried to calculate the distances but cannot keep separate routes.
I already tried this:
a_list=[]
visiting_time={}
for k in range(len(result)):
for (i,j) in visits[k]:
visiting_time[(i,j)]= distance_matrix_new_time[i][j]
f=list(visiting_time.values())
a_list.append(f)
In my code Result is the list with different routes (first list), and visits is the list with all edges (second list)
the output should be like this
[2,3,5,6,3,2,5,8,3,5,2,4,6],[2,6,3,1,9,....],[....] etc.
Can someone help me out?
you could use a list comprehension:
a_list = [[distance_matrix_new_time[i][j] for i, j in l] for l in visits]

How can I place networkx nodes with the most connections closer to the top?

I have a fairly large and messy network of nodes that I wish to display as neatly as possible.
This is how it's currently being displayed:
First, I tried playing with the layout to see if it could generate a good output automatically.
I have tried many different nx layouts, but they all display similar results. I have also tried answers from all of these stack exchange questions:
How to increase node spacing for networkx.spring_layout
Drawing a huge graph with networkX and matplotlib
NetworkX - Stop Nodes from Bunching Up - Tried Scale/K parameters
Fix position of subset of nodes in NetworkX spring graph
Here is the code I am using:
import networkx as nx
import matplotlib.pyplot as plt\
def generate_plot(connections, filename):
G=nx.Graph()
G.add_edges_from(connections)
nx.draw(G)
plt.show()
#plt.savefig(filename)
and here is the data that I am trying to display:
connections = [(0, 36), (0, 113), (2, 11), (2, 12), (2, 26), (2, 27), (2, 28), (2, 29), (2, 32), (2, 33), (2, 34), (2, 35), (2, 82), (3, 41), (4, 41), (5, 3), (6, 3), (11, 7), (11, 10), (11, 13), (11, 42), (12, 10), (12, 164), (26, 10), (26, 100), (27, 10), (27, 164), (28, 10), (28, 92), (29, 56), (29, 58), (29, 79), (29, 91), (29, 99), (29, 100), (29, 101), (29, 102), (30, 59), (30, 83), (30, 99), (31, 55), (31, 56), (31, 57), (31, 74), (31, 91), (31, 96), (31, 100), (31, 113), (31, 134), (31, 164), (32, 10), (33, 10), (34, 10), (34, 164), (35, 10), (35, 91), (35, 100), (36, 64), (36, 74), (36, 82), (36, 91), (36, 107), (36, 99), (38, 41), (39, 40), (39, 41), (39, 59), (40, 41), (40, 47), (40, 91), (40, 99), (41, 3), (41, 39), (41, 40), (43, 68), (43, 69), (45, 50), (46, 51), (46, 69), (46, 99), (47, 49), (47, 91), (47, 107), (47, 100), (47, 101), (47, 113), (48, 76), (50, 68), (50, 69), (51, 68), (51, 76), (51, 114), (52, 46), (52, 47), (52, 65), (53, 42), (53, 107), (53, 99), (53, 100), (53, 101), (53, 113), (54, 76), (55, 74), (55, 96), (55, 99), (56, 99), (56, 100), (56, 109), (57, 29), (57, 64), (57, 91), (57, 96), (57, 107), (57, 100), (58, 91), (58, 99), (58, 100), (58, 101), (58, 102), (59, 30), (59, 46), (59, 47), (59, 61), (59, 83), (59, 99), (59, 100), (59, 101), (60, 3), (60, 12), (60, 26), (60, 27), (60, 29), (60, 30), (60, 31), (60, 35), (60, 36), (60, 40), (60, 42), (60, 44), (60, 49), (60, 55), (60, 56), (60, 57), (60, 58), (60, 59), (60, 61), (60, 64), (60, 74), (60, 75), (60, 79), (60, 81), (60, 82), (60, 83), (60, 86), (60, 90), (60, 91), (60, 92), (60, 93), (60, 94), (60, 96), (60, 107), (60, 99), (60, 100), (60, 101), (60, 102), (60, 111), (60, 112), (60, 113), (60, 116), (60, 126), (60, 129), (60, 134), (60, 135), (60, 136), (60, 140), (60, 144), (60, 150), (60, 152), (60, 162), (60, 164), (60, 179), (60, 195), (61, 91), (61, 107), (61, 100), (61, 101), (61, 113), (61, 135), (62, 79), (62, 102), (63, 59), (64, 29), (64, 36), (64, 91), (64, 99), (64, 100), (64, 101), (64, 140), (65, 12), (65, 27), (65, 29), (65, 30), (65, 31), (65, 34), (65, 35), (65, 43), (65, 45), (65, 50), (65, 56), (65, 57), (65, 58), (65, 59), (65, 60), (65, 61), (65, 66), (65, 67), (65, 72), (65, 75), (65, 81), (65, 82), (65, 91), (65, 92), (65, 96), (65, 107), (65, 99), (65, 100), (65, 101), (65, 102), (65, 104), (65, 109), (65, 129), (65, 140), (65, 142), (65, 156), (65, 164), (67, 68), (67, 69), (67, 195), (68, 60), (69, 51), (69, 53), (69, 68), (69, 195), (70, 12), (70, 26), (70, 29), (70, 31), (70, 35), (70, 47), (70, 56), (70, 58), (70, 59), (70, 61), (70, 66), (70, 75), (70, 79), (70, 82), (70, 83), (70, 93), (70, 96), (70, 107), (70, 99), (70, 100), (70, 101), (70, 126), (70, 129), (70, 135), (70, 136), (70, 162), (70, 164), (71, 12), (71, 26), (71, 29), (71, 31), (71, 35), (71, 47), (71, 56), (71, 58), (71, 59), (71, 61), (71, 66), (71, 75), (71, 79), (71, 83), (71, 96), (71, 107), (71, 99), (71, 100), (71, 101), (71, 126), (71, 135), (71, 162), (71, 164), (72, 29), (72, 35), (72, 36), (72, 46), (72, 47), (72, 55), (72, 57), (72, 58), (72, 60), (72, 61), (72, 64), (72, 66), (72, 70), (72, 71), (72, 74), (72, 75), (72, 76), (72, 79), (72, 86), (72, 90), (72, 91), (72, 93), (72, 94), (72, 95), (72, 96), (72, 107), (72, 99), (72, 100), (72, 101), (72, 102), (72, 111), (72, 112), (72, 116), (72, 126), (72, 129), (72, 144), (73, 83), (74, 96), (74, 100), (75, 100), (76, 29), (76, 31), (76, 42), (76, 44), (76, 49), (76, 55), (76, 56), (76, 59), (76, 61), (76, 66), (76, 74), (76, 78), (76, 83), (76, 91), (76, 93), (76, 96), (76, 107), (76, 109), (76, 113), (76, 114), (76, 116), (76, 134), (76, 140), (77, 30), (77, 44), (77, 49), (77, 61), (77, 74), (77, 78), (77, 83), (77, 96), (77, 109), (77, 140), (78, 61), (78, 91), (78, 92), (79, 44), (79, 99), (80, 42), (80, 64), (80, 65), (80, 75), (80, 83), (80, 134), (80, 135), (80, 136), (80, 144), (80, 155), (81, 35), (81, 91), (81, 100), (82, 10), (83, 84), (83, 85), (83, 86), (83, 107), (83, 100), (84, 194), (84, 195), (87, 36), (87, 88), (87, 142), (87, 144), (88, 59), (88, 83), (88, 134), (88, 135), (88, 136), (88, 144), (88, 158), (88, 162), (89, 61), (89, 135), (89, 141), (90, 36), (91, 96), (91, 113), (93, 96), (93, 107), (93, 134), (93, 135), (94, 74), (94, 96), (95, 61), (95, 134), (95, 135), (95, 162), (96, 35), (96, 74), (96, 91), (96, 99), (96, 100), (96, 101), (98, 12), (98, 26), (98, 27), (98, 29), (98, 30), (98, 31), (98, 34), (98, 35), (98, 41), (98, 56), (98, 57), (98, 58), (98, 59), (98, 60), (98, 61), (98, 70), (98, 75), (98, 79), (98, 81), (98, 82), (98, 83), (98, 84), (98, 87), (98, 91), (98, 92), (98, 95), (98, 96), (98, 107), (98, 99), (98, 100), (98, 101), (98, 106), (98, 134), (98, 135), (98, 142), (98, 147), (98, 152), (98, 159), (99, 91), (99, 113), (99, 164), (100, 91), (100, 101), (100, 113), (100, 164), (101, 57), (101, 91), (101, 113), (101, 164), (102, 101), (103, 44), (103, 61), (103, 140), (104, 56), (104, 90), (104, 101), (104, 102), (104, 104), (104, 129), (104, 140), (105, 83), (105, 135), (106, 2), (106, 29), (106, 30), (106, 31), (106, 36), (106, 41), (106, 48), (106, 56), (106, 57), (106, 58), (106, 59), (106, 60), (106, 61), (106, 62), (106, 63), (106, 65), (106, 66), (106, 68), (106, 70), (106, 71), (106, 72), (106, 74), (106, 75), (106, 76), (106, 77), (106, 78), (106, 79), (106, 80), (106, 81), (106, 82), (106, 83), (106, 84), (106, 85), (106, 87), (106, 89), (106, 90), (106, 91), (106, 92), (106, 93), (106, 94), (106, 95), (106, 96), (106, 107), (106, 99), (106, 100), (106, 101), (106, 102), (106, 103), (106, 104), (106, 105), (106, 108), (106, 110), (106, 111), (106, 112), (106, 116), (106, 119), (106, 123), (106, 124), (106, 125), (106, 126), (106, 127), (106, 128), (106, 129), (106, 130), (106, 131), (106, 134), (106, 135), (106, 136), (106, 137), (106, 138), (106, 139), (106, 140), (106, 141), (106, 142), (106, 144), (106, 146), (106, 147), (106, 148), (106, 149), (106, 151), (106, 152), (106, 153), (106, 154), (106, 157), (106, 158), (106, 159), (106, 160), (106, 161), (106, 162), (106, 164), (106, 194), (108, 42), (108, 61), (108, 76), (108, 109), (108, 110), (108, 114), (109, 42), (109, 91), (109, 113), (109, 164), (110, 76), (111, 114), (112, 114), (114, 0), (114, 26), (114, 29), (114, 30), (114, 31), (114, 35), (114, 36), (114, 40), (114, 42), (114, 44), (114, 47), (114, 49), (114, 53), (114, 55), (114, 56), (114, 57), (114, 59), (114, 61), (114, 64), (114, 74), (114, 75), (114, 81), (114, 82), (114, 86), (114, 91), (114, 93), (114, 96), (114, 107), (114, 99), (114, 100), (114, 101), (114, 102), (114, 109), (114, 129), (114, 134), (114, 135), (114, 140), (114, 164), (114, 179), (115, 10), (115, 31), (115, 164), (116, 114), (119, 150), (120, 157), (121, 137), (122, 137), (123, 163), (124, 117), (124, 125), (124, 130), (124, 150), (124, 163), (125, 126), (126, 117), (126, 135), (127, 134), (128, 135), (129, 36), (129, 91), (130, 131), (131, 134), (131, 135), (132, 157), (133, 137), (134, 36), (134, 74), (134, 109), (134, 135), (135, 36), (135, 74), (135, 136), (135, 156), (136, 36), (137, 134), (138, 139), (139, 135), (140, 107), (140, 134), (140, 136), (141, 118), (141, 135), (141, 144), (142, 36), (142, 61), (142, 64), (142, 83), (142, 118), (142, 129), (142, 134), (142, 135), (142, 136), (142, 140), (142, 141), (142, 143), (142, 144), (142, 150), (142, 152), (142, 156), (142, 158), (142, 162), (142, 164), (142, 195), (143, 135), (144, 36), (144, 134), (144, 135), (144, 136), (144, 162), (145, 134), (146, 134), (146, 135), (146, 155), (147, 29), (147, 44), (147, 46), (147, 47), (147, 118), (147, 134), (147, 135), (147, 136), (147, 140), (147, 144), (147, 156), (147, 158), (147, 164), (148, 136), (148, 150), (149, 134), (149, 135), (149, 136), (149, 141), (150, 134), (150, 164), (151, 150), (152, 134), (152, 135), (152, 156), (152, 162), (153, 134), (153, 135), (153, 162), (154, 150), (155, 134), (156, 135), (157, 134), (158, 136), (158, 140), (159, 135), (160, 134), (160, 135), (160, 155), (162, 36), (162, 61), (162, 74), (162, 96), (162, 134), (162, 135), (162, 144), (167, 171), (168, 83), (169, 99), (170, 83), (170, 85), (171, 2), (172, 195), (173, 78), (174, 78), (175, 60), (175, 66), (175, 70), (175, 142), (176, 94), (176, 120), (176, 121), (176, 122), (176, 123), (176, 132), (176, 133), (176, 137), (176, 138), (176, 145), (176, 157), (177, 12), (177, 26), (177, 27), (177, 28), (177, 29), (177, 30), (177, 31), (177, 33), (177, 34), (177, 35), (177, 36), (177, 44), (177, 55), (177, 56), (177, 57), (177, 58), (177, 59), (177, 61), (177, 62), (177, 63), (177, 64), (177, 74), (177, 75), (177, 78), (177, 79), (177, 81), (177, 82), (177, 86), (177, 89), (177, 90), (177, 91), (177, 93), (177, 94), (177, 96), (177, 107), (177, 99), (177, 100), (177, 101), (177, 102), (177, 109), (177, 113), (177, 118), (177, 128), (177, 129), (177, 134), (177, 135), (177, 136), (177, 139), (177, 140), (177, 141), (177, 144), (177, 148), (177, 149), (177, 150), (177, 151), (177, 152), (177, 153), (177, 154), (177, 159), (177, 162), (178, 35), (180, 37), (182, 31), (183, 31), (184, 185), (185, 29), (185, 30), (185, 31), (185, 44), (185, 79), (185, 166), (185, 187), (185, 190), (187, 185), (188, 164), (188, 187), (188, 190), (189, 108), (190, 185), (192, 193), (195, 164)]
I am hoping to be able to spread out the nodes more and display them in a hierarchical manner, with the nodes that have the most connections closer to top, and the ones with few connections at the bottom.
This is a bit roundabout, but maybe useful:
The idea is to use the degree (i.e., its number of edges) of the node as y-coordinate, and then assign x-coords based on frequency of the given degree:
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
G=nx.Graph()
G.add_edges_from(connections)
# check how many times a given degree occurs:
degrees = [G.degree[a] for a in G.nodes]
# generate unique x-coordinates. divide by 2 for zero-centering:
degrees = {degree: [a for a in degrees.count(degree)/2. - np.arange(degrees.count(degree))] for degree in set(degrees)}
# build positioning dicitonary:
positions = {a : (degrees[G.degree[a]].pop(), G.degree[a]) for a in G.nodes}
Fixed distances in Y-direction, and slightly less compressed code:
degrees = [G.degree[a] for a in G.nodes]
degrees_unique = sorted(list(set(degrees)))
y_positions = {degrees_unique[i] : i for i in range(len(degrees_unique))}
x_positions = {}
for degree in degrees_unique:
x_positions[degree] = [a for a in degrees.count(degree) / 2. - np.arange(degrees.count(degree))]
positions = {}
for node in G.nodes:
deg = G.degree[node]
positions[node] = (x_positions[deg].pop(), y_positions[deg])
nx.draw(G, pos=positions, node_size=10)
alternatively, a mirror variable can be included in the last loop, s.t. nodes are plotted above and below the x-axis, every other iteration, somewhat decluttering everything:
mirror = 1
for node in G.nodes:
deg = G.degree[node]
positions[node] = (x_positions[deg].pop(), mirror*y_positions[deg])
mirror *= -1
nx.draw(G, pos=positions, node_size=10)

Changing the shape of a matrix using numpy

My question is two-fold. I have the following code to do with some matrices.
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)
The function takes a list of tuples and constructs a square binary matrix, where the entry at the location of each tuple is 1, and every other element is 0. The commented out code is simply to make sure that all rows sum to 1, which they do, so it's a valid binary matrix.
The problem I'm having is at this line: newMatrix = newMatrix[matrix]
when printing the shape after that, I'm getting that it's dimensions are 320*320*320; but what I'm looking for is 320*320.
Could someone explain to me A) Why this is happening, and B) How to reshape 'newMatrix' to be 320 by 320?
The code:
print( "numpy.eye(320) gives a matrix of shape:" , numpy.eye(320).shape )
gives:
numpy.eye(320) gives a matrix of shape: (320, 320)
This answers part B of your question. There is no need to reshape newMatrix because it is already (320, 320) .
So let's go over to part A of your question "Why is this happening that newMatrix after newMatrix = newMatrix[matrix] becomes 320x320x320 ?
The answer is: because using newMatrix[matrix] does exactly what it should do, create a 320x320x320 matrix.
You can save yourself a lot of work if you let NumPy do the indexing:
# 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)
Let's experiment with small 3x3 arrays:
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]])
Using mask as you do produces a (3,3,3) array:
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]]])
Changing mask to boolean, produces a 1d array, selecting values from arr that match the location of True in mask:
In [30]: arr[mask.astype(bool)]
Out[30]: array([0, 5, 7])
Another option is multiplication, which will zero out values, returning a (3,3):
In [31]: arr*mask
Out[31]:
array([[0, 0, 0],
[0, 0, 5],
[0, 7, 0]])
Or something similar with masked array:
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)
For your first question A), I suggest that you read this (Index arrays)
The use of index arrays can sometimes be non-intuitive, so see for instance the following matrix indexing:
import numpy as np
newMatrix = np.eye(2)
print newMatrix[0]
we get :
[ 1. 0.]
The result is the first element of the array along the largest dimension (dim 2), i.e. the first row of the matrix. Now, if we index using an array (notice the added brackets):
import numpy as np
newMatrix = np.eye(2)
print newMatrix[[0]]
we get :
[[ 1. 0.]]
This time, the result is still the first row of the matrix, but given in an array with a similar shape to the indexing array. From the page linked to above :
Generally speaking, what is returned when index arrays are used is an
array with the same shape as the index array, but with the type and
values of the array being indexed.
So I imagine numpy replacing the scalars in the indexing array with the matrix element given by that index scalar. If we try indexing with a matrix :
import numpy as np
indx = np.array([[1,0],[0,1]])
newMatrix = np.eye(2)
print newMatrix[indx]
gives us :
[[[ 0. 1.]
[ 1. 0.]]
[[ 1. 0.]
[ 0. 1.]]]
because every scalar in the indexing array is replaced by the corresponding row of the matrix in the result, thus also increasing the dimension of the result by 1 compared to the indexing array.
In your example, your final newMatrix is similar to your matrix, but where every scalar in matrix is replaced by either row 0 or 1 of your initial newMatrix, thus giving the final shape of your result.
This is probably not what you want, though. It might be interesting to have a look at boolean indexing. I suggest reading this (Boolean or “mask” index arrays)

Categories