洗牌 2D numpy 数组中的位置列表,然后将其用于 3D numpy 数组中的 select(或切片)

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

我正在使用一个 3D 数组,其索引数组是一个 200x200 二进制数组(用于分类)。该数组包含 0 或 1,我需要使用此数组 select 3D 数组中随机的 1000 个位置 0 和随机的 1000 个位置 1。我已经到了可以制作整数列表及其位置的地步,但我不知道如何随机化该列表并使用它来切片 3D 数组。

下面是我的代码。

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.

打印 'stack' 提供此功能。

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

从 'index' 二维数组生成值列表及其位置
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

匹配

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

我可以 select/slice 使用

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

这就是我卡住的地方。重申一下,我想从 3D 数组中随机切出 1000 个以 1 结尾的数组和 1000 个以 0 结尾的数组,我这辈子都不知道如何使用 'class_indexes' I'为此而生。

我想你想创建一个批处理并迭代它们?

您可以创建每个 class 的排列,然后 select 您想要的批次:

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

这应该适用于两个 类。如果你有两个以上 类 那就成问题了。

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)