3

So I have an array:

array([[[27, 27, 28],
        [27, 14, 28]],

       [[14,  5,  4],
        [ 5,  6, 14]]])

How can I iterate through it and on each iteration get the [a, b, c] values, I try like that:

for v in np.nditer(a):
    print(v)

but it just prints

27
27
28
27
14
28
14
5
4
5
6

I need:

[27 27 28]
[27 14 28]...
karambaq
  • 631
  • 3
  • 9
  • 24
  • 1
    As an aside: what is the calculation you want to do with the individual triplets? – 9769953 Sep 11 '18 at 14:45
  • @9769953 I need to convert hsv values to rgb – karambaq Sep 11 '18 at 14:49
  • 2
    It sounds like that can be done without iterating through the individual elements. If you add the formula, someone may show how to do that in one go. Or ask a new question on that. – 9769953 Sep 11 '18 at 14:51
  • Also: https://stackoverflow.com/questions/15278323/converting-image-from-rgb-to-hsv-color-space or https://stackoverflow.com/questions/24852345/hsv-to-rgb-color-conversion – 9769953 Sep 11 '18 at 14:53
  • Look at `ndindex`. It uses `nditer` to generate indices for a subarray, such as (2,2). Look at its code if possible. – hpaulj Sep 11 '18 at 15:00

6 Answers6

2

You could do something ugly as

for i in range(len(your_array)):
    for j in range(len(your_array[i])):
        print(your_array[i][j])
Shintlor
  • 742
  • 6
  • 19
2
b = a.reshape(-1, 3)
for triplet in b:
    ...
blue_note
  • 27,712
  • 9
  • 72
  • 90
2

Apparently you want to iterate on the first 2 dimensions of the array, returning the 3rd (as 1d array).

In [242]: y = np.array([[[27, 27, 28],
     ...:         [27, 14, 28]],
     ...: 
     ...:        [[14,  5,  4],
     ...:         [ 5,  6, 14]]])

Double loops are fine, as is reshaping to a (4,2) and iterating.

nditer isn't usually needed, or encouraged as an iteration mechanism (its documentation needs a stronger disclaimer). It's really meant for C level code. It isn't used much in Python level code. One exception is the np.ndindex function, which can be useful in this case:

In [244]: for ij in np.ndindex(y.shape[:2]):
     ...:     print(ij, y[ij])
     ...:     
(0, 0) [27 27 28]
(0, 1) [27 14 28]
(1, 0) [14  5  4]
(1, 1) [ 5  6 14]

ndindex uses nditer in multi_index mode on a temp array of the specified shape.

Where possible try to work without iteration. Iteration, with any of these tricks, is relatively slow.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
0

Think of it as having arrays within an array. So within array v you have array a which in turn contains the triplets b

import numpy as np
na = np.array

v=na([[[27, 27, 28], [27, 14, 28]], [[14,  5,  4],[ 5,  6, 14]]])

for a in v:
    for b in a:
        print b

Output:

[27 27 28]
[27 14 28]
[14  5  4]
[ 5  6 14]

Alternatively you could do the following,

v2 = [b for a in v for b in a]

Now all your triplets are stored in v2

[array([27, 27, 28]),
 array([27, 14, 28]),
 array([14,  5,  4]),
 array([ 5,  6, 14])]

..and you can access them like a 1D array eg

print v2[0]

gives..

array([27, 27, 28])
DrBwts
  • 3,470
  • 6
  • 38
  • 62
0

Another alternative (useful for arbitrary dimensionality of the array containing the n-tuples):

a_flat = a.ravel()
n = 3   
m = len(a_flat)/n
[a_flat[i:i+n] for i in range(m)]

or in one line (slower):

[a.ravel()[i:i+n] for i in range(len(a.ravel())/n)]

or for further usage within a loop:

for i in range(len(a.ravel())/n):
    print a.ravel()[i:i+n]
Jojo
  • 427
  • 3
  • 8
0

Reshape the array A (whose shape is n1, n2, 3) to array B (whose shape is n1 * n2, 3), and iterate through B. Note that B is just A's view. A and B share the same data block in the memory, but they have different array headers information where records their shapes, and changing values in B will also change A's value. The code below:

    a = np.array([[[27, 27, 28],[27, 14, 28]],
                  [[14,  5,  4],[ 5,  6, 14]]])   
    b = a.reshape((-1, 3))   
    for last_d in b:
        a, b, c = last_d
        # do something with last_d or a, b, c
yann
  • 652
  • 7
  • 14