Vahni
Vahni

Reputation: 272

numpy.where() returns inconsisten dimensions

I pass an array of size (734,814,3) to a function but numpy.where() gives one dimensional result instead of the two-dimensional one, which it should for a 2D array

def hsi2rgb(img):
    img_rgb = np.empty_like(img)
    h = img[:,:,0] #(734,814)
    s = img[:,:,1] #(734,814)
    i = img[:,:,2] #(734,814)
    l1 = 0.00
    l2 = 2*3.14/3
    l3 = 4*3.14/3
    l4 = 3.14
    r1 = np.where(np.logical_and(h>=l1, h<l2)) #(99048,)
    r2 = np.where(np.logical_and(h>=l2, h<l3))
    r3 = np.where(np.logical_and(h>=l3, h<l4))
    hs = h[r1]
    return img_rgb

r1 is shown to be a tupple, and r1[0],r1[1] are of the size 99048, which shouldn't be the case. r1 should have row indices and column indices of those values which satisfy the condition. I tried it without the logical and, using just one condition, but the problem persists.

Upvotes: 0

Views: 1117

Answers (1)

user6655984
user6655984

Reputation:

I followed your code, and np.where returned the expected result: a tuple with two 1D arrays containing the indexes where the condition is met:

import numpy as np
h = np.random.uniform(size=(734, 814))
r1 = np.where(np.logical_and(h >= 0.1, h < 0.9))
print(r1[0].shape, r1[1].shape)    # (478129,) (478129,)

This means that 478129 elements met the condition. For each of them, r1[0] will have its row index, and r11 will have its column index. Namely, if r1 looks like

(array([  0,   0,   0, ..., 733, 733, 733]), array([  0,   1,   2, ..., 808, 809, 811]))

then I know that h[0, 0], h[0, 1], h[0, 2], etc satisfy the conditions: the row index comes from the first array, the column index from the second. This structure may be less readable, but it's usable for indexing the array h.

The transposed form of the output is more readable, being a 2D array with row-column index pairs:

array([[  0,   0],
       [  0,   1],
       [  0,   2],
       ...,
       [733, 808],
       [733, 809],
       [733, 811]])

It can be obtained by transposing r1 (if you need the original r1 as well), or directly with np.argwhere:

r1 = np.argwhere(np.logical_and(h >= 0.1, h < 0.9))

Upvotes: 2

Related Questions