user14438759
user14438759

Reputation:

Loop through arrays manually

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

Answers (4)

mathfux
mathfux

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

Ironkey
Ironkey

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

Prune
Prune

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

Martin Gustafsson
Martin Gustafsson

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

Related Questions