Convert adjacency matrix to array of edges - python

I want to be able to convert an adjacency matrix to array of edges. Currently I know only how to conver an array of edges to adjacency matrix:
E = [[0, 0], [0, 1], [1, 1], [2, 0]]
size = len(set([n for e in E for n in e]))
adjacency_matrix = [[0] * size for _ in range(size)]
for sink, source in E:
adjacency_matrix[sink][source] = 1
>> print(adjacency_matrix)
[[1, 1, 0], [0, 1, 0], [1, 0, 0]]
but is there a possibility to reverse this process?

If you need pure python, use a list comprehension:
adjacency_matrix = [[1, 1, 0], [0, 1, 0], [1, 0, 0]]
E = [[i,j] for i,l in enumerate(adjacency_matrix) for j, x in enumerate(l) if x]
output: [[0, 0], [0, 1], [1, 1], [2, 0]]

Try this
E = np.stack(np.where(adjacency_matrix)).T
Add tolist() if you want a list
Output (with tolist())
[[0, 0], [0, 1], [1, 1], [2, 0]]
EDIT: my bad I thought OP was using numpy, so here it is in numpy

Yes, it's possible and easy, just iterate through your matrix using two nested cycles, for example:
adjacency_matrix = [[1, 1, 0], [0, 1, 0], [1, 0, 0]]
E = []
for i in range(size):
for j in range(size):
if adjacency_matrix[i][j] == 1:
E.append([i, j])
print(E)
Output:
[[0, 0], [0, 1], [1, 1], [2, 0]]

You could make a function for it:
def adj_to_edges(A):
edges = []
for i,row in enumerate(A):
for j,b in enumerate(row):
if b == 1:
edges.append([i,j])
return edges
print(adj_to_edges([[1, 1, 0], [0, 1, 0], [1, 0, 0]]))
#[[0, 0], [0, 1], [1, 1], [2, 0]]

Related

Manipulating an array afterward so that the rows and column depends on the size of two strings

I am trying to manipulate array2 so that the row and column is dependent on the len of the strings as for array1
str1 = "Hi"
str2 = "Bye"
array1 = [[[0, 0] for y in range(len(str2)+1)] for x in range(len(str1)+1)]
print(array1)
#output: [[[0, 0], [0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0], [0, 0]]]
array2 = [[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
#want array2 to implement same format as array1 where the row and column is determined by the len of str1 and str2
temp = [[[array2[i], array2[j]] for y in range(len(str2)+1)] for x in range(len(str1)+1)] #does not work
I tried to remove some brackets from temp however, did not work.
I tried to manipulate the method I used for array1, but did not work. I was expecting the rows and columns to be dependent on the len of the strings as for array2.
The current code has no idea what to do with array2[i], array2[j] cause neither i nor j have been defined.
This code is working as expected (I've organized the output for better readability):
str1 = "Hi"
str2 = "Bye"
array1 = [[[0, 0] for y in range(len(str2)+1)] for x in range(len(str1)+1)]
print(array1)
#output is 4x3: [
#[[0, 0], [0, 0], [0, 0], [0, 0]],
#[[0, 0], [0, 0], [0, 0], [0, 0]],
#[[0, 0], [0, 0], [0, 0], [0, 0]]]
array2 = [[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
temp = [[[0, 0] for y in range(len(str2)+1)] for x in range(len(str1)+1)]
#output is 4x3: [
#[[0, 0], [0, 0], [0, 0], [0, 0]],
#[[0, 0], [0, 0], [0, 0], [0, 0]],
#[[0, 0], [0, 0], [0, 0], [0, 0]]]
If you want to use a certain set of numbers from the array, you need to change the code to:
i, o = 0, 1
temp = [[[array2[i], array2[j]] for y in range(len(str2)+1)] for x in range(len(str1)+1)]
If this doesn't solve your problem, please provide further explanation

Replacing values in a list by looping without making the size of the list smaller/larger

I have a list li. When I loop over it and replace zeros with new values the size of the list changes. I want to keep the same size but be able to manipulate the list.
str0 = "Hi"
str1 = "Bye"
li = [[[0, 0] for y in range(len(str1)+1)] for x in range(len(str0)+1)] #correct size
print(li)
#output: [[[0, 0], [0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0], [0, 0]]]
print(li[0][0][0])
#output: 0
for i in range(0, len(str0) + 1):
li[i][0] = i
print(li)
#output of incorrect size:[[0, [0, 0], [0, 0], [0, 0]], [1, [0, 0], [0, 0], [0, 0]], [2, [0, 0], [0, 0], [0, 0]]]
print(li[0][0][0])
#output: Typeerror
Note output should be: where column = 0, row = i according to the loop
If I get your explanation correct you would like to have
print(li)
[[[0, 0], [0, 0], [0, 0], [0, 0]],
[[1, 1], [0, 0], [0, 0], [0, 0]],
[[2, 2], [0, 0], [0, 0], [0, 0]]]
For that you can do one of the following:
# a)
for i in range(0, len(str0) + 1):
li[i][0] = [i, i]
a solution I found here:
# b)
for i in range(0, len(str0) + 1):
li[i][0] = [i]*2
or like this
# c)
import numpy as np
# rest of your code
li = np.array(li)
for i in range(0, len(str0) + 1):
li[i][0][:] = i
li = list(li)
Hope that will help you

how to convert one-hot vectors to multi-label?

I have a multi-classification task, and I have gotten the one-hot type predictions like
[[0, 1, 1],
[0, 1, 0],
[1, 0, 1]]
I wish to convert this one-hot vector to labels like
[[1, 2], [1], [0, 2]]
I have tried tf.argmax, but it doesn't work. So how can I deal with it?
Using list comprehensions:
oheList = [[0, 1, 1],
[0, 1, 0],
[1, 0, 1]]
[[i for i in range(len(el)) if el[i]==1] for el in oheList]
# [[1, 2], [1], [0, 2]]
Another way to solve the problem,
import numpy as np
arr = np.array([[0, 1, 1],
[0, 1, 0],
[1, 0, 1]])
result = {}
for r, c in zip(*np.where(arr == 1)):
result.setdefault(r, []).append(c)
print(result.values())
[[1, 2], [1], [0, 2]]

Smart Indexing with numpy

I have an 4 dimensional array (named colors) which assigns a color (ie 3 values R, G, B) to each 3d point (x, y, z) -> (r, g, b)
I have another 2 dimensional array (named visible) which tells me which z pane I can see when I look down on it (x, y)->z
I want to create 3 dimensional array (view) which tells me what I see. (x, y) -> (r, g, b)
How can I do that with numpy smart indexing?
I tried
colors=np.array([
[
[[0, 0, 0], [1, 0, 0]],
[[0, 1, 0], [0, 0, 1]]],
[
[[1, 0, 1], [1, 1, 0]],
[[0, 1, 1], [1, 1, 1]]]])
visible=np.array(
[[0, 1],
[1, 0]])
view=colors[:, :,visible[:, :]]
expected=np.array(
[[[0, 0, 0], [1, 1, 0]],
[[0, 1, 1], [0, 0, 1]]])
But that gives me 5 dimensional array.
You can use this:
x = np.array([[0,1],[0,1]])
y = np.array([[0,0],[1,1]])
colors[(visible, y, x)]
It gives:
array([[[0, 0, 0],
[1, 1, 0]],
[[0, 1, 1],
[0, 0, 1]]])
x and y select which pixels you want, while visible is your z plane selector. They can actually be 1D and they will broadcast to fill the other dimension. You can construct arbitrary-size x and y like this:
x = np.arange(colors.shape[2])
y = np.arange(colors.shape[1]).reshape(-1,1) # transpose
Your problem was quite interesting and challenging.
Numpy's advanced indexing works a bit other like you tried to use it intuitively.
There are more options to achieve what you want:
1. You can use advanced indexing as follows using with a bit help of numpy.indices():
import numpy as np
colors=np.array([
[
[[0, 0, 0], [1, 0, 0]],
[[0, 1, 0], [0, 0, 1]]],
[
[[1, 0, 1], [1, 1, 0]],
[[0, 1, 1], [1, 1, 1]]]])
visible = np.array(
[[0, 1],
[1, 0]])
x_ind, y_ind = np.indices(visible.shape)
view = colors[visible, x_ind, y_ind]
print(view)
Out:
[[[0 0 0]
[1 1 0]]
[[0 1 1]
[0 0 1]]]
2. Alternatively you can use numpy.choose() which is very intuitive way in this case:
import numpy as np
colors=np.array([
[
[[0, 0, 0], [1, 0, 0]],
[[0, 1, 0], [0, 0, 1]]],
[
[[1, 0, 1], [1, 1, 0]],
[[0, 1, 1], [1, 1, 1]]]])
visible = np.array(
[[0, 1],
[1, 0]])
visible = visible.reshape(2,2,1)
view = np.choose(visible, colors)
print(view)
Out:
[[[0 0 0]
[1 1 0]]
[[0 1 1]
[0 0 1]]]

Initialize 2d array with variable size

Using the following method:
myArray = [0,1] * NUM_ITEMS
Desired result (2d array):
[[0,1],[0,1],[0,1]...]
Actual result (extended 1d array):
[0,1,0,1,0,1...]
How can I achieve the desired result preferably without using numpy?
A list comprehension should do the trick:
>>> NUM_ITEMS = 5
>>> my_array = [[0, 1] for _ in range(NUM_ITEMS)]
>>> my_array
[[0, 1], [0, 1], [0, 1], [0, 1], [0, 1]]
Since you tagged arrays, here's an alternative numpy solution using numpy.tile.
>>> import numpy as np
>>> NUM_ITEMS = 10
>>> np.tile([0, 1], (NUM_ITEMS, 1))
array([[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1]])

Categories

Resources