How to replace ndarray with a number? - python

I have the following code:
arr = zip(*people2)
for i in range(len(arr)):
for j in range(len(arr[i])):
for k in range(len(arr[i][j])):
if(arr[i][j][k] == 1):
arr[i][j] = k
break
There is an array of arrays of arrays. I need to replace these last arrays with numbers.
Like this:
[
[[1, 0, 0], [2, 0, 0]],
[[3, 0, 0], [4, 0, 0]],
]
->
[
[1, 2],
[3, 4]
]
Numbers here are just for example.
How can I do this? I tried to use numpy.resize(), but it doesn't work.

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

Convert adjacency matrix to array of edges

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]]

Iterating through list of lists of lists

I am trying to iterate through a 3-D list in python(not numpy but I am willing to convert to a numpy array if this makes it easier) in such a way that from a list like this:
a = [[[0, 0], [3, 0]], [[1, 0], [4, 0]], [[2, 0], [6, 0]] ]
I can get the output
[0,0]
[1,0]
[2,0]
[3,0]
[4,0]
[6,0]
I can't figure out how to make it iterate like this...
My code:
a = [[[0, 0], [0, 0]], [[1, 0], [0, 0]], [[2, 0], [0, 0]] ]
for i in range(len(a)):
for z in range(len(a[i])):
print(a[i][z])
I've tried different things but can't seem to get this output.
I think you want to print the nth sub-sublists consecutively from each sublist. You could unpack and zip a to get an iterable of tuples, then print each pair in them:
for tpl in zip(*a):
for pair in tpl:
print(pair)
Output:
[0, 0]
[1, 0]
[2, 0]
[3, 0]
[4, 0]
[6, 0]
Try:
print(*[i for v in zip(*a) for i in v], sep="\n")
Prints:
[0, 0]
[1, 0]
[2, 0]
[3, 0]
[4, 0]
[6, 0]
In case you want to just traverse the elements column wise, you can convert the list to numpy array, then stack the columns and print:
import numpy as np
a = [[[0, 0], [3, 0]], [[1, 0], [4, 0]], [[2, 0], [6, 0]] ]
arr = np.stack(np.array(a), axis=1)
for p in arr:
for x in p:
print(x)
The solution below is based on the previous assumption of printing each item in the sublist based on sorted order:
You can use itertools to flatten the 3d to 2d list and then sort the 2d list based on first element in each sublist. Then print the sorted list.
import itertools
a = [[[0, 0], [3, 0]],[[1, 0], [4, 0]],[[2, 0], [6, 0]]]
flat_list = list(itertools.chain(*a))
sorted_list = sorted(flat_list, key=lambda x: x[0])
for i in sorted_list:
print(i)
This is the correct way of iterating like you're trying to do:
a = [[[0, 0], [0, 0]], [[1, 0], [0, 0]], [[2, 0], [0, 0]] ]
for i in range(len(a)):
for z in range(len(a[i])):
print((a[i])[z])
If it is simpler for you, instead of iterating on the length of the lists with an index, try iterating on the elements of the lists:
a = [[[0, 0], [0, 0]], [[1, 0], [0, 0]], [[2, 0], [0, 0]] ]
for a1 in a:
for a2 in a1:
print(a2)

Selecting components of vectors in array

I have a tensor with shape (7, 2, 3)
I want to select one of the two row vectors from each of the 7 2x3 matrices, i.e.
[
[[0, 0, 0],
[1, 1, 1]],
[[0, 0, 0],
[1, 1, 1]],
...x7
]
to
a = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
...x7
]
b = [
[1, 1, 1],
[1, 1, 1],
[1, 1, 1]
...x7
]
each with shape (7, 3).
How can I do this without reshape? (I find reshape to be kind of confusing when some dimensions are the same).
I also know of
np.array(map(lambda item: item[0], x)))
but I would like a more concise way if there is one.
just use looped indexing: data[:, i, :] where i loops from 0 through 1
import numpy as np
a = np.array([
[[0, 0, 0],
[1, 1, 1]],
[[0, 0, 0],
[1, 1, 1]]
])
print(a[:, 1, :])
will produce
[[1 1 1]
[1 1 1]]

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]]]

Categories

Resources