Python Forum
np.where on 3Darray => result remains a 3D array
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
np.where on 3Darray => result remains a 3D array
#1
Hi,

In the following test case, i'm looking for a way to extract rows from a 3D array, but i want that the results remains a 3D array; in otherway, i want to extract a part of the 3D array

Obviously:
  • here there's a single row per subarray but in the "real life" the number of rows differs from a study to another
  • i'm sure that the number of rows remains identical per subarray => that's why a 3D array is possible
  • prior to play with "reshape" (with also depends on the block size), i'm wondering if something ever exist in numpy (without using a loop)

import numpy as np

M = np.array([[[ 6,  9,  4],
               [ 0,  2,  1],
               [10, 15, 30]],
              [[ 9,  0,  1],
               [ 4,  6,  4],
               [ 0,  3,  9]],
              [[ 6,  7,  4],
               [ 0,  1,  6],
               [ 1,  5,  1]]])

index = np.where(np.isin(M[:, :, 0], 0))
print(index)
Mprime = M[index]
Reply
#2
Quote:i'm wondering if something ever exist in numpy (without using a loop)

Internally, numpy must loop over all of data to find rows with 0, even if you do not see that on the surface. I think numpy doesn't find the zeroes by magic!

Quote:here there's a single row per sub-array but in the "real life" the number of rows differs from a study to another

Do you mean the sub-array, like data[0][0] : [ 6, 9, 4] might also be a list of lists? We would need some extra magic to cater for that possibility.

Quote:# from numpy docs
isin is an element-wise function version of the python keyword in.
isin(a, b) is roughly equivalent to np.array([item in b for item in a]) if a and b are 1-D sequences.

Like this perhaps:

res = np.array([row for d in data for row in d if row[0] == 0])
Finds:

Output:
array([[0, 2, 1], [0, 3, 9], [0, 1, 6]])
Starting with this data:

# given this data
data = [[[ 6,  9,  4],
       [ 0,  2,  1],
       [10, 15, 30]],
      [[ 9,  0,  1],
       [ 4,  6,  4],
       [ 0,  3,  9]],
      [[ 6,  7,  4],
       [ 0,  1,  6],
       [ 1,  5,  1]]]

# generators are very small, good when data is very large
# a generator to find all rows with zero in
res_gen_all = (row for d in data for row in d if 0 in row)
for r in res_gen_all:
    print(r)
Finds:

Output:
[0, 2, 1] [9, 0, 1] [0, 3, 9] [0, 1, 6]
Find all rows starting with zero:

# a generator to find all rows that start with zero
res_gen_0 = (row for d in data for row in d if row[0] == 0)
for r in res_gen_0:
    print(r)
Finds:

Output:
[0, 2, 1] [0, 3, 9] [0, 1, 6]
Or like this find the data set number and index number of the data set:

res_gen_all_index = ((d,i,data[d][i]) for d in range(len(data)) for i in range(len(data[d])) if 0 in data[d][i])
for r in res_gen_all_index:
    print(r)
Finds:

Output:
(0, 1, [0, 2, 1]) (1, 0, [9, 0, 1]) (1, 2, [0, 3, 9]) (2, 1, [0, 1, 6])
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020