Create co-occurrence matrix from edges of the graph - python-3.x

I have graphs with parallels edges(more than one edges) as shown below
G=nx.read_edgelist('file.txt',create_using=nx.MultiGraph(), nodetype=int)
Example output
(1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4)
now here I want to create the co-occurrence matrix from this graph
example output
1 2 3 4
1 0 13 17 24
2 13 0
etc
How can i do so? Most of the solutions from stack overflow are for word co-occurrence
Any help will be much appreciated

You could use the Counter from the collections module:
from collections import Counter
G = ...
cocounts = Counter(list(G.edges()))
# Then just allocate a list (2x4) or something and create the matrix:
res = [[0 for c in range(4)] for r in range(2)]
for cocount, count in cocounts.items():
res[cocount[0]-1][cocount[1]-1] = count

Related

Find coordinates that are outside a radius

I'm a beginner with Python. I need to get the number of arrows (points) that are outside the radius. I do know what the answer is, but how do I get that output in Python?
This is what I have:
points = [(4, 5), (-0, 2), (4, 7), (1, -3), (3, -2), (4, 5), (3, 2), (5, 7), (-5, 7), (2, 2), (-4, 5), (0, -2),(-4, 7), (-1, 3), (-3, 2), (-4, -5), (-3, 2), (5, 7), (5, 7), (2, 2), (9, 9), (-8, -9)]
center = (0,0)
radius = 9
You could use a list comprehension:
import math
points = [(4, 5), (-0, 2), (4, 7), (1, -3), (3, -2), (4, 5), (3, 2), (5, 7),
(-5, 7), (2, 2), (-4, 5), (0, -2), (-4, 7), (-1, 3), (-3, 2), (-4, -5),
(-3, 2), (5, 7), (5, 7), (2, 2), (9, 9), (-8, -9)]
center = (0, 0)
radius = 9
points_outside_radius = [
p
for p in points
if math.sqrt((p[0] - center[0]) ** 2 + (p[1] - center[1]) ** 2) > radius
]
num_points_outside_radius = len(points_outside_radius)
print(f'There are {num_points_outside_radius} points outside the radius:')
print(points_outside_radius)
Output:
There are 2 points outside the radius:
[(9, 9), (-8, -9)]
Note I used the full euclidian distance formula in case you need to change the center to something other than the origin.

Python 3 : why my "and" functions as "or" in "if" conditions

I'm writing a function to get coordinates of neighbours of a certain cell in orthogonal coordinates based on coordinates of the selected cell. My code is:
def get_neighbours_coordinates (x, y):
neighbours = []
for temp_x in [x-1, x, x+1]:
# condition to drop the case, when cell has the same coordinates as treated
for temp_y in [y-1, y, y+1]:
if (temp_x != x) and (temp_y != y):
neighbours.append((temp_x, temp_y))
print (neighbours)
Then, if I'm calling it as (for a sake of example):
for i in range (10):
get_neighbours_coordinates(i, i)
It returns:
[(-1, -1), (-1, 1), (1, -1), (1, 1)]
[(0, 0), (0, 2), (2, 0), (2, 2)]
[(1, 1), (1, 3), (3, 1), (3, 3)]
[(2, 2), (2, 4), (4, 2), (4, 4)]
[(3, 3), (3, 5), (5, 3), (5, 5)]
[(4, 4), (4, 6), (6, 4), (6, 6)]
[(5, 5), (5, 7), (7, 5), (7, 7)]
[(6, 6), (6, 8), (8, 6), (8, 8)]
[(7, 7), (7, 9), (9, 7), (9, 9)]
[(8, 8), (8, 10), (10, 8), (10, 10)]
While it supposed to return:
[(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1), (2, 2)]
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2), (3, 3)]
[(2, 2), (2, 3), (2, 4), (3, 2), (3, 4), (4, 2), (4, 3), (4, 4)]
[(3, 3), (3, 4), (3, 5), (4, 3), (4, 5), (5, 3), (5, 4), (5, 5)]
[(4, 4), (4, 5), (4, 6), (5, 4), (5, 6), (6, 4), (6, 5), (6, 6)]
[(5, 5), (5, 6), (5, 7), (6, 5), (6, 7), (7, 5), (7, 6), (7, 7)]
[(6, 6), (6, 7), (6, 8), (7, 6), (7, 8), (8, 6), (8, 7), (8, 8)]
[(7, 7), (7, 8), (7, 9), (8, 7), (8, 9), (9, 7), (9, 8), (9, 9)]
[(8, 8), (8, 9), (8, 10), (9, 8), (9, 10), (10, 8), (10, 9), (10, 10)]
It looks like and dropped all cases where at least one of the conditions is true, while it has to drop only case where both conditions are true.
What is wrong with my code?
P.S. If I replace and with or, the code returns the desired output.
Using Python 3.9 on Windows 10.
The results you are seeing are consistent with your Boolean logic. By saying and you are saying that you want to exclude both the entire row and column of the cell in question. The only cell you really want to exclude is the query cell itself.
That is, you want:
not (temp_x == x and temp_y == y)
which is the same as:
(temp_x != x) or (temp_y != y)
This logical equivalence is one of De Morgan's Laws.

How can I get combinations with respect to value and without respect to order in python?

For example, all of the below should return [(2,2)] because all the tuple elements in the returned lists are the same with respect to value.
>>> list(combinations([2,2,2],2))
[(2, 2), (2, 2), (2, 2)]
>>> list(combinations_with_replacement([2,2],2))
[(2, 2), (2, 2), (2, 2)]
>>> list(combinations_with_replacement([2,2,2],2))
[(2, 2), (2, 2), (2, 2), (2, 2), (2, 2), (2, 2)]
>>> list(combinations([i,i,i],2))
[(2, 2), (2, 2), (2, 2)]

Connectivity between two items having an intermediate item as the connection in python

This is the code that i have written which basically describes the flight connectivity having one city in common between the source and the destination. It seems right for most of the test cases but isn't satisfying this particular one.
def onehop(lis):
hop=[]
for (i,j) in lis:
for (k,l) in lis:
if i==k and j!=l:
return sorted(lis)
if (i!=k and j!=l)and(i==l or j==k) and (((i,j) not in hop) and ((k,l) not in hop)):
m=lis.pop(lis.index((i,j)))
n=lis.pop(lis.index((k,l)))
hop.extend([m,n])
for i in range(len(hop)):
if hop[i][0]>hop[i][1]:
hop[i]=(hop[i][1],hop[i][0])
ans=sorted(hop,key=lambda item: (item[0],item[1]))
return ans
onehop([(2,3),(1,2),(3,1),(1,3),(3,2),(2,4),(4,1)])
Output I expected:
[(1, 2), (1, 3), (1, 4), (2, 1), (3, 2), (3, 4), (4, 2), (4, 3)]
Output I obtained:
[(1, 2), (1, 3), (2, 3), (2, 4), (3, 1), (3, 2), (4, 1)]
def onehop(lis):
hop=[]
for (i,j) in lis:
for (k,l) in lis:
if j==k and i!=l :
hop.append([i,l])
unique = [list(x) for x in set(tuple(x) for x in hop)]
ans=sorted(unique,key=lambda item: (item[0],item[1]))
ans1 = [tuple(l) for l in ans]
return(ans1)

Python: Split list into list of lists

Suppose that I have list:
list = [(4, 7), (3, 7), (5, 7), (4, 6), (4, 8), (2, 7), (3, 6), (3, 8), (6, 7)]
That I want to divide the list into sublists of lengths: [2, 3, 4] (these lengths can vary)
To produce: sublist_list = [[(4, 7), (3, 7)],[(5, 7), (4, 6), (4, 8)], [(2, 7), (3, 6), (3, 8), (6, 7)]]
What's the quickest way that I can do this? Thanks in advance.
myList = [(4, 7), (3, 7), (5, 7), (4, 6), (4, 8), (2, 7), (3, 6), (3, 8), (6, 7)]
listOfLengths = [2, 3, 4]
def getSublists(listOfLengths,myList):
listOfSublists = []
for i in range(0,len(listOfLengths)):
if i == 0:
listOfSublists.append(myList[:listOfLengths[i]])
else:
listOfSublists.append(myList[listOfLengths[i-1]:listOfLengths[i-1]+listOfLengths[i]])
return listOfSublists
Then if you call getSublists on your myList (original list input) and listOfLengths (a list containing the length of your sublists), you get
#In: getSublists(listOfLengths,myList)
#Out: [[(4, 7), (3, 7)], [(5, 7), (4, 6), (4, 8)], [(4, 6), (4, 8), (2, 7), (3, 6)]]
You can user list[i:j] feature in python which returns a new list contains
list[i] to list[j-1] elements of original list.
base = 0
Lengths =[] #list of lengths
for num in Length:
sub_list.append(List[base:num+base])
base += num #jump to next length
What about simply iterating the list and appending to the new lists?
c = 0
for sublist in list:
sublistlist[len(sublistlist)-1].append(sublist)
c += 1
if c % 2:
sublistlist.append([])

Resources