jeudi 6 décembre 2018

Shuffling list of locations in a 2D numpy array and then use it to select (or slice) in a 3D numpy array

I'm working with a 3D array of which the index array is a 200x200 binary array (for classification). This array contains either 0 or 1 and I need to use this array select a random 1000 locations of 0 and a random 1000 locations of 1 in the 3D array. I've gotten to the point where I can make a list of integers and their location and I cannot figure out how to randomize that list and use it to slice the 3D array.

What follows is my code.

index = file.read(1) #a 200 x 200 2D array. it's binary and only contains 1s and 0s in varying clusters.
array1 = file.read(1) #a 200x 200 2D array #first array in the stack this is repeated for the remaining 3
stack = np.dstack((array1, array2, array3, array4, index)) #Note location of 'index'. Also this is now a 3d array.

Printing 'stack' provides this.

print(stack)

[[[0.5580524  0.4883823  0.45231035 0.48734677 0.48952746 0.5680048
   0.61111915 0.7087597  0.68731683 0.7544603  0.74395233 0.76797485
   0.6963369  0.551183   1.        ]

...

[0.4401738  0.3988781  0.35379404 0.36442786 0.36919853 0.46986657
   0.4414228  0.4944533  0.47824454 0.5220391  0.56117916 0.6202841
   0.6201752  0.64005166 0.        ]]]

Now to generate a list of values and their positions from 'index' 2D array using numpy.where

class_indexes = {}
for class_ in np.unique(index):
    class_indexes[class_] = np.where(index == class_)

The results of calling class_indexes is below

class_indexes
{0: (array([   1,    1,    1, ..., 1511, 1511, 1511]),
  array([1797, 1798, 1799, ..., 2001, 2002, 2003])),
 1: (array([   1,    1,    1, ..., 1511, 1511, 1511]),
  array([1833, 1834, 1835, ..., 1962, 1963, 1964]))}

additionally

len(class_indexes[0][0])
280000

len(class_indexes[1][1])
120000

Matches

np.unique(index, return_counts = True)
(array( 0,  1], dtype=int16), array([280000, 120000]))

I can select/slice a specific location in the 3D array using

print(stack[50:51,75:76])
[[[0.444261   0.43989536 0.47133848 0.4160257  0.5548938  0.44350675
   0.6010795  0.48953462 0.6352046  0.5407316  0.72074664 0.69200116
   0.58779025 0.5807785  1.        ]]]

or

print(stack[50,75])
[0.444261   0.43989536 0.47133848 0.4160257  0.5548938  0.44350675
 0.6010795  0.48953462 0.6352046  0.5407316  0.72074664 0.69200116
 0.58779025 0.5807785  1.        ]

This is where I get stuck. To reiterate, I want to randomly slice 1000 of the ones that end in 1 and 1000 of the ones that end in 0 from the 3D array and I cannot for the life of me figure out how to use the 'class_indexes' I've generated to do this.




Aucun commentaire:

Enregistrer un commentaire