Перемешивание списка мест в двумерном массиве и затем его использование для выбора (или среза) в трехмерном массиве - PullRequest
0 голосов
/ 06 декабря 2018

Я работаю с трехмерным массивом, индексным массивом которого является двоичный массив 200x200 (для классификации).Этот массив содержит либо 0, либо 1, и мне нужно использовать этот массив, чтобы выбрать случайные 1000 местоположений из 0 и случайные 1000 местоположений из 1 в трехмерном массиве.Я дошел до того, что могу составить список целых чисел и их местоположение, и я не могу понять, как рандомизировать этот список и использовать его для нарезки трехмерного массива.

Ниже приведен мой код.

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.

Это обеспечивает печать «стека».

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.        ]]]

Теперь для создания списка значений и их позиций из двумерного массива «индекс» с помощью numpy.where

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

Результаты вызова class_indexes ниже

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]))}

дополнительно

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]))

Я могу выбрать / вырезать определенное место в 3Dиспользуя массив

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.        ]]]

или

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.        ]

Вот где я застрял.Повторюсь, я хочу случайным образом нарезать 1000 из тех, которые заканчиваются на 1, и 1000 из тех, которые заканчиваются на 0, из трехмерного массива, и я не могу на всю жизнь понять, как использовать сгенерированные мной «class_indexes»сделать это.

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Это должно работать с двумя классами.Если у вас более двух классов, это становится проблемой.

import numpy as np

allindices = np.mgrid[0:200, 0:200].swapaxes(0, 2).swapaxes(0, 1)
allzeroes = allindices[index2 == 0]
randomzeroes = allzeroes[np.random.randint(0, allzeroes.shape[0], size=2000), :] #size = sample size.
newarray = index[randomzeroes[:,0], randomzeroes[:,1], :]

np.set_printoptions(threshold=np.nan) #removes truncation during print
print(newarray)
0 голосов
/ 06 декабря 2018

Полагаю, вы хотите создать пакет и выполнить итерации по ним?

Вы можете создать перестановку каждого класса и затем выбрать нужный пакет:

p1 = np.random.permutation(280000) // use the length of the class instead of the fixed value
p2 = np.random.permutation(120000)

for i in range(0, batch_size, 120000):
   class_indexes[0][p1[i:i+batch_size]]
   class_indexes[1][p2[i:i+batch_size]]

Конечно,из-за отброшенных 160000 элементов это немного напрасно, но вы все равно можете использовать эти данные, имея два индекса и создавая новую перестановку, когда это необходимо.

Проверьте каждый элемент индексации, чтобы увидеть, что он делает:

p1[i:i+batch_size]

А потом

class_indexes[0][p1[i:i+batch_size]]
...