How to iterate random_path in the below code? - python

I want to print random_path in the below code. Can I show all random paths using list
random_path = nx.generate_random_paths(twitch_G,100, path_length = 5)

If I got your question right, you just need to put random_path inside list list( random_path )
gr = nx.gnp_random_graph(10, 0.6)
list( nx.generate_random_paths(gr, sample_size=2, path_length=4) )
result:
[[1, 9, 0, 4, 7], [6, 7, 3, 0, 5]]

Related

Compare each first sublist with the rest and group the second sublist from the list if they pass condition

My input data is
mylist = [[[1820, 57, 1920, 237], [2, 3, 3]], [[1830, 90, 1920, 240], [2, 3, 4]], [[1450, 0, 1667, 197], [1, 3, 6]], [[1835, 90, 1920, 240], [0, 5, 7]],[[1452, 0, 1667, 197], [9, 9, 9]]]
I have a group of rectangle data with the first sublist containing its coordinates and the second one containing rgb data. I would like to group the second sublist if they overlap. Below is the code to check whether rectangle overlap.
def isRectangleOverlap(self, R1, R2):
if (R1[0] >= R2[2]) or (R1[2] <= R2[0]) or (R1[3] <= R2[1]) or (R1[1] >= R2[3]):
return False
else:
return True
And I have the following code:
for i in range(len(mylist)):
for j in range(i + 1, len(mylist)):
if isRectangleOverlap(mylist[i][0], mylist[j][0]):
....
if they pass the condition, the second sublist will be grouped together.
My expected output:
[[[2, 3, 3], [2, 3, 4], [0, 5, 7]], [[1, 3, 6], [9, 9, 9]]]
Do you have any suggestions?
UPDATE: I solved the problem with answers below but I have another question that is it possible group RGB data of retangles that cluster in a small area like this ?
file1
file2
It is an interesting question, because there are a few curve balls. For one, you are not looking for overlapping rectangles, but for clusters of rectangles. Your desired result implies that. I tried to be explicit in the code below:
mylist = [[[1820, 57, 1920, 237], [2, 3, 3]], [[1830, 90, 1920, 240], [2, 3, 4]], [[1450, 0, 1667, 197], [1, 3, 6]], [[1835, 90, 1920, 240], [0, 5, 7]],[[1452, 0, 1667, 197], [9, 9, 9]]]
# R= [Ly, Lx, Ry, Rx] = (LowerLeft-Y, LowerLeft-X, UpperRight-Y, UpperRight-X)
clusters = {}
#will hold end results, clustering overlapping rectangels together by key in mylist
#{
# 1: [1,2]
#}
def isRectangleOverlap(R1: list, R2: list):
if (R1[0] >= R2[2]) or (R1[2] <= R2[0]) or (R1[3] <= R2[1]) or (R1[1] >= R2[3]):
return False
else:
return True
def hasAlreadyOverlapped(key: int):
for k, v in clusters.items():
if key in v:
return k
return None
#itterate over every set of Rectangle,RGB combination
for i in range(len(mylist)):
cur_rect = mylist[i][0]
current_cluster = None
#check if current rectangle has already overlapped with previous rectangles,
#and if so, any new overlappings with current rectangle will be added to that cluster
#otherwise a new cluster will be created with current index i
current_cluster = hasAlreadyOverlapped(i) or i+1
#if this is a new cluster, then initiate it with current rectange in it
if not (current_cluster in clusters):
clusters[current_cluster] = [i]
#check remaining rectangles in mylist for overlapping, and add them to current cluster
#unless of course, if this is the last item.
if i < len(mylist)-1:
for j in range(i+1, len(mylist)):
if isRectangleOverlap(cur_rect, mylist[j][0]):
#this rectangle could already overlapped with a previouws processed rectangle, so we
#need to check for that.
if not (j in clusters[current_cluster]):
clusters[current_cluster].append(j)
print(clusters)
#> {1: [0, 1, 3], 3: [2, 4]}
result = []
for _, rectangles in clusters.items():
c = []
for i in rectangles:
c.append(mylist[i][1])
result.append(c)
print(result)
#> [[[2, 3, 3], [2, 3, 4], [0, 5, 7]], [[1, 3, 6], [9, 9, 9]]]
Note that there is one problem here that I haven't accounted for. Let's say, rect0 and rect8 overlap, and rect3 and rect4 overlap. The above code would make clusters. But what if both clusters overlap with rect9 (rect9 stretching both over rect8 and rect3)?
I will have another thought about it later today, fun question!
UPDATE
I had another moment to think about it and I came up with a better solution, using recursion. The above solution, as explained, iterates over rectangles and sees if there is any overlap (creating clusters). However, two independent clusters cannot be merged later on when encountering a bridging rectangle. To counter this effect, the logic would be that you explore a cluster when you find one, and after you have exhausted the current cluster of overlapping rectangles, you move on to new rectangles that form new clusters.
See the code below, I have amended a bit (created a class for example for Rectangles) for readability.
class Rectangle():
"""
Making the objects in your list a bit more readable
"""
def __init__(self, lleft_y: int, lleft_x: int, uright_y:int, uright_x:int, rgb: list) -> None:
self.lleft_y = lleft_y
self.lleft_x = lleft_x
self.uright_y = uright_y
self.uright_x = uright_x
self.rgb = rgb
mylist = [
Rectangle(1820, 57, 1920, 237, [2, 3, 3]),
Rectangle(1830, 90, 1920, 240, [2, 3, 4]),
Rectangle(1450, 0, 1667, 197, [1, 3, 6]),
Rectangle(1835, 90, 1920, 240, [0, 5, 7]),
Rectangle(1452, 0, 1667, 197, [9, 9, 9])]
# This list will hold all clusters of overlapping rectangles by their index
clusters: list[list[int]] = []
# This list will keep track of all already processed rectangles by their index
processed_rectangles: list[int] = []
def doRectanglesOverlap(R1: Rectangle, R2: Rectangle):
# if (R1 above of R2) or (R1 below of R2) or (R1 left of R2) or (R1 right of R2)
if (R1.lleft_y >= R2.uright_y) or (R1.uright_y <= R2.lleft_y) or (R1.uright_x <= R2.lleft_x) or (R1.lleft_x >= R2.uright_x):
return False
else:
return True
def find_overlapping(index: int) -> list[int]:
# First find all rectangles directly overlapping with current rectangle
result: list[int] = []
for j in range(len(mylist)):
# If this rectangle was already processed because it was part of another cluster, just skip it
if j in processed_rectangles:
continue
if doRectanglesOverlap(mylist[index], mylist[j]):
processed_rectangles.append(j)
result.append(j)
# Now, for each found overlapping rectangle, we want to find the overlapping rectangles as well,
# effectively exploring the cluster outward. Recursive functions can be handy!
for r in result:
result += find_overlapping(r)
return result
# Looping over all rectangles
for i in range(len(mylist)):
# If this rectangle was already processed because it was part of another cluster, just skip it
if i in processed_rectangles:
continue
processed_rectangles.append(i)
# If it was not part of another earlier processed cluster, it is a new cluster. Let's add it.
current_cluster = [i]
# Now, we are going to loop over all remaining rectangles that haven't been processed yet, and add it to the current cluster
other_rectangles = find_overlapping(i)
# Due to the recursion, `other_rectangles` now hold the entire rest of the cluster.
current_cluster = current_cluster + (other_rectangles)
clusters.append(current_cluster)
print(clusters)
#> [[0, 1, 3], [2, 4]]
result = []
for ix, cluster in enumerate(clusters):
result.append([])
for i in cluster:
result[ix].append(mylist[i].rgb)
print(result)
#> [[[2, 3, 3], [2, 3, 4], [0, 5, 7]], [[1, 3, 6], [9, 9, 9]]]
A simple version that sets found items to an empty list. This is not very efficient since the list to compare to doesn't get shorter.
import copy
mylist = [[[1820, 57, 1920, 237], [2, 3, 3]], [[1830, 90, 1920, 240], [2, 3, 4]], [[1450, 0, 1667, 197], [1, 3, 6]], [[1835, 90, 1920, 240], [0, 5, 7]],[[1452, 0, 1667, 197], [9, 9, 9]]]
def isRectangleOverlap(R1, R2):
if (not R1) or (not R2):
return False
if (R1[0] >= R2[2]) or (R1[2] <= R2[0]) or (R1[3] <= R2[1]) or (R1[1] >= R2[3]):
return False
else:
return True
mylist2 = copy.deepcopy(mylist)
grouped = []
for i in range(len(mylist)):
grouped.append([])
for j in range(i + 1, len(mylist)):
if isRectangleOverlap(mylist[i][0], mylist2[j][0]):
if not grouped[i]: # include the i'th sublist
grouped[i].append(mylist[i][1])
grouped[i].append(mylist[j][1])
mylist2[j] = [[], []]
grouped = [sublst for sublst in grouped if sublst]
print(grouped)
A bit more complicated way that removes the items from the list so it doesn't check them again:
mylist2 = copy.deepcopy(mylist)
grouped = []
for i in range(len(mylist)):
grouped.append([])
inds_2_remove = []
for j in range(len(mylist2)):
if mylist[i] == mylist2[j]:
inds_2_remove.append(j)
continue
if isRectangleOverlap(mylist[i][0], mylist2[j][0]):
if not grouped[i]:
grouped[i].append(mylist[i][1])
grouped[i].append(mylist2[j][1])
inds_2_remove.append(j)
for ind_2_remove in reversed(inds_2_remove):
print(ind_2_remove)
del mylist2[ind_2_remove]
grouped = [sublst for sublst in grouped if sublst]
print(grouped)

Median of the medians of a list

I need a vector that stores the median values of the medians of the main list "v". I have tried something with the following code but I am only able to write some values in the correct way.
v=[1,2,3,4,5,6,7,8,9,10]
final=[]
nfac=0
for j in range (0,4):
nfac=j+1
for k in range (0,nfac):
if k%2==0:
final.append(v[10/2**(nfac)-1])
else:
final.append(v[9-10/2**(nfac)])
The first median in v=[1,2,3,4,5,6,7,8,9,10] is 5
Then I want the medians of the remaining sublists [1,2,3,4] and [6,7,8,9,10]. I.e. 2 and 8 respectively. And so on.
The list "final" must be in the following form:
final=[5,2,8,1,3,6,9,4,7,10]
Please take a note that the task as you defined it is basically equivalent to constructing a binary heap from an array.
Definitely start by defining a helper function for finding the median:
def split_by_median(l):
median_ind = (len(l)-1) // 2
median = l[median_ind]
left = l[:median_ind]
right = l[median_ind+1:] if len(l) > 1 else []
return median, left, right
Following the example you give, you want to process the resulting sublists in a breadth-first manner, so we need a queue to remember the following tasks:
from collections import deque
def construct_heap(v):
lists_to_process = deque([sorted(v)])
nodes = []
while lists_to_process:
head = lists_to_process.popleft()
if len(head) == 0:
continue
median, left, right = split_by_median(head)
nodes.append(median)
lists_to_process.append(left)
lists_to_process.append(right)
return nodes
So calling the function finally:
print(construct_heap([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])) # [5, 2, 8, 1, 3, 6, 9, 4, 7, 10]
print(construct_heap([5, 1, 2])) # [2, 1, 5]
print(construct_heap([1, 0, 0.5, -1])) # [0, -1, 0.5, 1]
print(construct_heap([])) # []

Create a multiset from a Set X

in a Multiset it is allowed to have multiple elements
For Example. if X (normal set) = {0,2,4,7,10}, then ∆X (multiset) = {2,2,3,3,4,5,6,7,8,10}.
∆X denotes the multiset of all 􏰃(N 2) pairwise distances between points in X
How can i Write this in Python?
I have created a List X but i don't know how to put all differences in another list and order them.
I hope you can help me.
It is basically just one line.
import itertools
s = {0,2,4,7,10}
sorted([abs(a-b) for (a,b) in itertools.combinations(s,2)])
you can use itertools
import itertools
s = {0,2,4,7,10}
k = itertools.combinations(s,2)
distance = []
l = list(k)
for p in l:
distance.append(abs(p[1]-p[0]))
print(sorted(distance))
A simple way is to convert your set to a list, sort it, and then use a double for loop to compute the differences:
X = {0,2,4,7,10} # original set
sorted_X = sorted(list(X))
diffs = []
for i, a in enumerate(sorted_X):
for j, b in enumerate(sorted_X):
if j > i:
diffs.append(b-a)
print(diffs)
#[2, 4, 7, 10, 2, 5, 8, 3, 6, 3]
And if you want the diffs sorted as well:
print(sorted(diffs))
#[2, 2, 3, 3, 4, 5, 6, 7, 8, 10]
Another option that would work in this case is to use itertools.product:
from itertools import product
print(sorted([(y-x) for x,y in product(sorted_X, sorted_X) if y>x]))
#[2, 2, 3, 3, 4, 5, 6, 7, 8, 10]

How to print numpy objects without line breaks

I am logging input arguments to a function using
logging.debug('Input to this function = %s',
inspect.getargvalues(inspect.currentframe())[3])
But I do not want the line breaks inserted within numpy objects. numpy.set_printoptions(linewidth=np.nan) removes some, but line breaks are still inserted in 2D objects such as
array([[ 0.84148239, 0.71467895, 0.00946744, 0.3471317 ],
[ 0.68041249, 0.20310698, 0.89486761, 0.97799646],
[ 0.22328803, 0.32401271, 0.96479887, 0.43404245]])
I want it to be like this:
array([[ 0.84148239, 0.71467895, 0.00946744, 0.3471317 ], [ 0.68041249, 0.20310698, 0.89486761, 0.97799646], [ 0.22328803, 0.32401271, 0.96479887, 0.43404245]])
How can I do this? Thanks.
Given an array x, you can print it without line breaks with,
import numpy as np
x_str = np.array_repr(x).replace('\n', '')
print(x_str)
or alternatively using the function np.array2string instead of np.array_repr.
I'm not sure if there is an easy way to remove newlines from the string representation or numpy arrays. However, it is always possible to remove them after the conversion took place,
input_args = inspect.getargvalues(inspect.currentframe())[3]
logging.debug('Input to this function = %s', repr(input_args).replace('\n', ''))
import numpy as np
np.set_printoptions(threshold=np.inf)
np.set_printoptions(linewidth=np.inf)
# Testing:
big_arr = np.ones([30,70])
print(big_arr)
Simple solution
import numpy as np
value = np.array([[1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 7, 8]])
value_str = str(value).replace('\n', '')
print("prints: " + value_str)
# prints: [[1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 7, 8]]
This solution also works:
myArray = np.array([[ 0.84148239, 0.71467895, 0.00946744, 0.3471317 ],
[ 0.68041249, 0.20310698, 0.89486761, 0.97799646],
[ 0.22328803, 0.32401271, 0.96479887, 0.43404245]])
print(np.array2string(myArray).replace('\n','').replace(' ',', '))
Output:
[[0.84148239, 0.71467895, 0.00946744, 0.3471317, ], [0.68041249, 0.20310698, 0.89486761, 0.97799646], [0.22328803, 0.32401271, 0.96479887, 0.43404245]]

In Python how can I change the values in a list to meet certain criteria

In Python, I have several lists that look like variations of:
[X,1,2,3,4,5,6,7,8,9,X,11,12,13,14,15,16,17,18,19,20]
[X,1,2,3,4,5,6,7,8,9,10,X,12,13,14,15,16,17,18,19,20]
[0,X,2,3,4,5,6,7,8,9,10,11,X,13,14,15,16,17,18,19,20]
The X can fall anywhere. There are criteria where I put an X, but it's not important for this example. The numbers are always contiguous around/through the X.
I need to renumber these lists to meet a certain criteria - once there is an X, the numbers need to reset to zero. Each X == a reset. Each X needs to become a zero, and counting resumes from there to the next X. Results I'd want:
[0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,10]
[0,1,2,3,4,5,6,7,8,9,10,0,1,2,3,4,5,6,7,8,9]
Seems like a list comprehension of some type or a generator could help me here, but I can't get it right.
I'm new and learning - your patience and kindness are appreciated. :-)
EDIT: I'm getting pummeled with downvotes, like I've reposted on reddit or something. I want to be a good citizen - what is getting me down arrows? I didn't show code? Unclear question? Help me be better. Thanks!
Assuming the existing values don't matter this would work
def fixList(inputList, splitChar='X'):
outputList = inputList[:]
x = None
for i in xrange(len(outputList)):
if outputList[i] == splitChar:
outputList[i] = x = 0
elif x is None:
continue
else:
outputList[i] = x
x += 1
return outputList
eg
>>> a = ['X',1,2,3,4,5,6,7,8,9,'X',11,12,13,14,15,16,17,18,19,20]
>>> fixList(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> b = ['y',1,2,3,4,5,6,7,8,9,10,'y',12,13,14,15,16,17,18,19,20]
>>> fixList(b, splitChar='y')
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
EDIT: fixed to account for the instances where list does not start with either X or 0,1,2,...
Using the string 'X' as X and the_list as list:
[0 if i == 'X' else i for i in the_list]
This will return the filtered list.

Categories