Reputation:
I am trying to replicate how zip works by using a simple example and i want the output to be an array. I have the following data
s = (2, 2)
array = np.zeros(s)
x = np.array([1, 0, 1, 0, 1, 1, 1, 1])
y = np.array([1, 0, 0, 0, 1, 0, 1, 1])
What i want to do is have a 2x2 matrix as output, which works like this:
for i, j in zip(x, y):
array[i][j] += 1
This outputs
[[2 0]
[2 4]]
I tried obtaining the same results without using the zip for lists but i get a (1,1) tuple
for i in range(len(x)):
array = x[i], y[i]
will output: (1, 1)
Upvotes: 2
Views: 57
Reputation: 5939
In order to do it in a vectorized way, try to work on array.ravel()
instead. This command performs dynamic changes of array
:
np.add.at(array.ravel(),
np.ravel_multi_index(np.array([x,y]), s),
np.repeat(1, len(x)))
So you can check out after running it that array
has changed:
>>> array
array([[2, 0],
[2, 4]])
Upvotes: 0
Reputation: 2607
import numpy as np
array = np.zeros(2, dtype=int)
x = np.array([1, 0, 1, 0, 1, 1, 1, 1])
y = np.array([1, 0, 0, 0, 1, 0, 1, 1])
# empirically what zip does
[(x[i], y[i]) for i in range(sorted([len(x), len(y)])[0])]
#proof
print( list(zip(x, y)) == [(x[i], y[i]) for i in range(sorted([len(x), len(y)])[0])] )
True
Why use sorted?
Since zip stops at the index of the smaller list we need to iterate by the range of the smallest list; therefore sorted([1,2])[0]
is 1
(the smaller of the 2)
so even if i had y = np.array([1, 0, 0, 0, 1, 0, 1, 1, 1])
that would still return the correct zip of the 2
Upvotes: 0
Reputation: 77837
This makes the transformation clear for you
for idx in range(len(x)):
i = x[idx]
j = y[idx]
array[i][j] += 1
print(array)
Output:
[[2 0]
[2 4]]
Upvotes: 0
Reputation: 303
for i in range(len(x)):
array[x[i]][y[i]] += 1
This will do the same as
for i, j in zip(x, y):
array[i][j] += 1
Upvotes: 1