Find indices of line intersection in shapely - python

I would like to find a better solution for what I am proposing below. I am trying to find the indices associated with a line intersection when using the shapely library. Solutions from other libraries are welcome.
Right now I am iterating through the location coordinates and storing the index where an intersection is observed. I would like to do away with the loop and create a more streamlined function.
The code below results in a single intersection/crossing.
line_crossings = []
latitude = [10, 11, 12, 13, 14, 15, 16, 17 ,18]
longitude = [7, 9, 11, 13, 17, 19, 23, 25 ,29]
location = np.column_stack((latitude, longitude))
C = (14.5, 14.5)
D = (12.3, 12.5)
line2 = LineString([C, D])
for idx in range(0, len(location)-1):
A = (latitude[idx], longitude[idx])
B = (latitude[idx+1], longitude[idx+1])
line1 = LineString([A, B])
int_pt = line2.intersection(line1)
if int_pt.type == 'Point':
print(int_pt)
line_crossings.append(idx)
Update
It would seem the quickest way to get the coordinates of the crossings is as follows:
latitude = [10, 11, 12, 13, 14, 15, 16, 17 ,16, 15, 14, 13, 12, 11, 10]
longitude = [7, 9, 11, 13, 17, 19, 23, 25 ,29, 25, 23, 13, 13, 13, 11]
location = LineString([i for i in zip(latitude,longitude)])
C = (14.5, 14.5)
D = (12.3, 12.5)
gate = LineString([C, D])
[[i.x, i.y] for i in location.intersection(gate)]
But I need to be able to get the index in the location variable where the intersection occurs. Is it possible to get this using the list comprehension?

Related

Finding coordinate of maximum value in list of lists

I am tasked with finding the exact coordinate of a maximum value in a list of lists in python. This list of lists is referred to as a grid to emulate topographical coordinates.
Here is the grid, along with my code to find the maximum:
grid = [[15, 16, 18, 19, 12, 11],
[13, 19, 23, 21, 16, 12],
[12, 15, 17, 19, 22, 10],
[10, 14, 16, 13, 9, 6]]
maxi = 0
for i in grid:
for j in i:
if j > maxi:
maxi = j
This code finds the maximum, however I am stuck on finding the coordinates. The output should be:
global max: (1,2) 23
Because the maximum (23) is on the First row, and on the second column.
I have tried using index and find but they do not work or take my value as an input. Any tips or help are appreciated, thank you in advance.
You can use the builtin function enumerate.
Update your code to this:
grid = [[15, 16, 18, 19, 12, 11],
[13, 19, 23, 21, 16, 12],
[12, 15, 17, 19, 22, 10],
[10, 14, 16, 13, 9, 6]]
maxi = -float('inf')
maxCoord = None
for i, row in enumerate(grid):
for j, col in enumerate(row):
if col > maxi:
maxi = col
maxCoord = (i, j)
print(maxCoord, maxi) #(1, 2) 23
Enumerate could be an option, as it was already proposed. If you want to keep your original function to find the max value, you can call its coordinates using:
for sublist in grid:
if maxi in sublist:
print(grid.index(sublist), sublist.index(maxi))

Python f-string and append()

I hope y'all doing fine!
So I want to make 5 groups of 6 people randomly chosen from a list and then append those 6 chosen names to the special group.
Example: If a, b, c, d, e, f, are the first six chosen names -> append those names to group1;
after the group1 contains 6 names, then the next 6 names -> append to group2; and so and so till I have 5 groups of 6 people.
I hope you understand me and that you can help :)
My code:
import random
names = [30 names i dont wanna share]
group1 = list()
group2 = list()
group3 = list()
group4 = list()
group5 = list()
def choosegroup():
def chooserandom():
return(random.choice(names))
def creategroup():
for i in range(1,7):
chosed = chooserandom()
names.remove(chosed)
#while(chosed in group1):
#print('Ups')
#print(chosed + ' already chosed')
# chosed = chooserandom()
#print(chosed)
group1.append(chosed)
#print('Group 1:' + '\n' + str(group1) + '\n')
createdgroup = creategroup()
print(group1)
for i in range(1,6):
print(f'Group {i}')
choosegroup()
group1.clear()
random.shuffle(names)
groups = [ names[i:i+6] for i in range(0, len(names), 6) ]
Now groups[0], groups[1] etc. are your 6-person groups.
Once you have your list of names, to split them into random groups, I would instead use numpy
import numpy as np
groups = np.array(names)
np.shuffle(groups)
groups = np.reshape(groups, (5,6))
As an example with numbers instead of names
>>> names = np.arange(30)
>>> names
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
>>> np.random.shuffle(names)
>>> names
array([ 8, 18, 23, 7, 25, 14, 11, 20, 13, 24, 15, 26, 19, 21, 12, 17, 0,
6, 3, 10, 29, 9, 16, 28, 22, 5, 1, 4, 27, 2])
>>> np.reshape(names, (5,6))
array([[ 8, 18, 23, 7, 25, 14],
[11, 20, 13, 24, 15, 26],
[19, 21, 12, 17, 0, 6],
[ 3, 10, 29, 9, 16, 28],
[22, 5, 1, 4, 27, 2]])
You can access them from globals as such:
globals()[f"group{i}"]
though storing and retrieving them from a dictionary is preferable.
You can rewrite your code as follows:
import random
from collections import defaultdict
names = [30 names i dont wanna share]
groups = defaultdict(list)
def choosegroup(group_name):
def chooserandom():
return(random.choice(names))
def creategroup(group_name):
for i in range(1,7):
chosed = chooserandom()
names.remove(chosed)
groups[group_name].append(chosed)
createdgroup = creategroup()
print(group_name, "\n", group[group_name])
for i in range(1,6):
print(f'Group {i}')
group_name = f"group{i}"
choosegroup(group_name)
groups[group_name].clear()

Find communities in a graph with Louvain

I read T0.pkl that contains a directed graph created with networkx, thus I've turned that one in a igraph graph.
Next, I applied Louvain to the graph and now I've a louvain.VertexPartition.ModularityVertexPartition and I don't know how to use it
G0_nx = nx.read_gpickle("../snapshots_original/T0.pkl")
G0_nx_edges = list(G0_nx.edges)
G0_nx_nodes = list(G0_nx.nodes)
G0_ig = igraph.Graph(directed=True)
G0_ig.add_vertices(G0_nx_nodes)
G0_ig.add_edges(G0_nx_edges)
partition = louvain.find_partition(G0_ig, lv.ModularityVertexPartition)
First you can plot it to visualize the clustering:
igraph.plot(partition)
If you try to print it with a simple
print(partition)
you will obtain something similar to:
Clustering with V elements and n clusters
[cluster_id]: node1, node2, node3... (the nodes in the n-th cluster)
For example:
Clustering with 33 elements and 3 clusters
[0] 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
[1] 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
[2] 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
Afterwards you can access the nodes within a cluster just like using a list with the desired cluster id as index:
print(partition[1])
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
You should also check the Louvain library docs, where other features such as temporal community detection are outlined.

How to swap the new added number into the correct position in binary heap?

This question of my homework has passed a list where index 1 is the new node and is also the root. Then I have to check if it's children is smaller then itself and swap it with the smaller child. I've written some code but it's not working.
def perc_down(data):
count = 0
index = 1
l, r = 2 * index, 2 * index + 1
while index < len(data):
if data[index] > data[l] and data[index] > data[r]:
min_i = data.index(min(data[l], data[r]))
data[index], data[min_i] = data[min_i], data[index]
count += 1
index = min_i
return count
values = [0, 100, 7, 8, 9, 22, 45, 12, 16, 27, 36]
swaps = perc_down(values)
print('Binary heap =',values)# should be [0, 7, 9, 8, 16, 22, 45, 12, 100, 27, 36]
print('Swaps =', swaps)# should be 3
Give l and r values inside the while loop
while index <= len(data) // 2:
l, r = 2 * index, 2 * index + 1
if r >= len(data):
r = index
if data[index] > data[l] or data[index] > data[r]:
min_i = data.index(min(data[l], data[r]))
data[index], data[min_i] = data[min_i], data[index]
count += 1
index = min_i
print(data) #Added this for easy debugging.
return count
And run the loop till half values only because it's binary min heap.
Output:
[0, 7, 100, 8, 9, 22, 45, 12, 16, 27, 36]
[0, 7, 9, 8, 100, 22, 45, 12, 16, 27, 36]
[0, 7, 9, 8, 16, 22, 45, 12, 100, 27, 36]
Binary heap = [0, 7, 9, 8, 16, 22, 45, 12, 100, 27, 36]
Swaps = 3
Revised the algorithm for those indices whose children do not exist.
For : values = [0, 100, 7, 11, 9, 8, 45, 12, 16, 27, 36] for 100 after 2 swaps comes at index 5 which does not have a right child so when it exceeds the length of list we just set it back to original index.
Heapified list : Binary heap = [0, 7, 8, 11, 9, 36, 45, 12, 16, 27, 100].

python numpy polyfit function

I'm new to python and haven't found an answer on this site so far.
I'm using numpy.polyfit in a loop and getting an error as below and don't understand as when I run the code in debug everything works fine and the len of arrays going into the function are the same:
Error Runtime exception: TypeError: expected x and y to have same length
My code is below:
import numpy as np
from collections import defaultdict
bb = [ 10, 11, 12, 22, 10, 11, 12, 11, 10, 11, 12, 22, 10, 11, 12, 11, 10, 11, 12, 22, 10, 11, 12, 11, 10, 11, 12, 22, 10, 11, 12, 11, 10 ]
i = 0
b = -3
bb_gradient = defaultdict(dict)
while ( b <= 0 ):
print i
print len(range(3))
print len(bb[b-3:b])
bb_gradient[i][0], _ = np.polyfit( range(3), weekly_bb_lower[b-3:b], 1 )
i += 1
b += 1
What am I doing wrong?
Thanks in anticipation.
I am assuming bb is weekly_bb_lower. Change while ( b <= 0 ) to while ( b < 0 ). because when b becomes 0, weekly_bb_lower[-3:0] will return an empty list. a list[-n:0] is supposed to be empty.
You can avoid referencing an empty list by moving the last three elements to the start of your list:
import numpy as np
from collections import defaultdict
bb = [ 10, 11, 12, 22, 10, 11, 12, 11, 10, 11, 12, 22, 10, 11, 12, 11, 10, 11, 12, 22, 10, 11, 12, 11, 10, 11, 12, 22, 10, 11, 12, 11, 10 ]
bb = bb[-3:] + bb[:-3] # moves the last three elements of the list to the start prior to looping
bb_gradient = defaultdict(dict)
for i in range(3):
bb_gradient[i][0], _ = np.polyfit( range(3) , bb[i:i+3], 1 )
Prashanth's explanation is correct.

Categories

Resources