如何在python中将一个包含随机数的函数应用于numpy数组的行?

时间:2016-04-29 06:09:36

标签: python arrays numpy

所以我有一个形状为(28, 28, 60000)的3D数组,对应60000个28x28图像。我想通过使用以下函数获得每个图像的随机24x24块:

def crop(X):
    x = random.randint(0,3)
    y = random.randint(0,3)
    return X[x:24+x, y:24+y,]

但是,如果我将函数crop(X)应用于我的矩阵X,则会返回每个样本中的相同块。如何确保每个样本使用不同的随机生成的xy值?

2 个答案:

答案 0 :(得分:1)

这是我的尝试。

基本上这个想法是你必须以某种方式将矩阵从最后一个维度分开(numpy不允许你应用不是一维数组的东西)。您可以使用dsplit执行此操作,并使用dstack将其重新组合在一起。

然后,您将在每个组件上应用裁剪功能。作为简化示例:

import random

a = np.array(range(300)).reshape(10,10,3)

def crop(X):
    x = random.randint(0,3)
    y = random.randint(0,3)
    return X[x:3+x, y:3+y]

# we can loop over each component of the matrix by first splitting it
# off the last dimension:
b = [np.squeeze(x) for x in np.dsplit(a, a.shape[-1])]

# this will recreate the original matrix
c = np.dstack(b)

# so putting it together with the crop function
get_rand_matrix = [crop(np.squeeze(x)) for x in np.dsplit(a, a.shape[-1])]
desired_result = np.dstack(get_rand_matrix)

答案 1 :(得分:0)

这里是一个矢量化通用(用于处理非方形数组)方法,使用NumPy broadcastinglinear indexing生成 one-go中所有图像的切片生成3D数组输出,如此 -

# Store shape
m,n,N = A.shape # A is the input array

# Set output block shape
out_blk_shape = (24,24)

x = np.random.randint(0,m-out_blk_shape[0]-1,(N))
y = np.random.randint(0,n-out_blk_shape[1]-1,(N))

# Get range arrays for the block across all images
R0 = np.arange(out_blk_shape[0])
R1 = np.arange(out_blk_shape[1])

# Get offset and thus all linear indices. Finally index into input array.
offset_idx = (y*n*N + x*N) + np.arange(N)
all_idx = R0[:,None]*n*N + R1*N + offset_idx[:,None,None]
out = A.ravel()[all_idx]

示例运行 -

1)输入:

In [188]: A = np.random.randint(0,255,(6,7,2)) # Input array

In [189]: # Set output block shape
     ...: out_blk_shape = (3,2) # For demo reduced to a small shape
          # Rest of the code stays the same.

In [190]: x  # To select the start columns from the slice
Out[190]: array([1, 0])

In [191]: y  # To select the start rows from the slice
Out[191]: array([1, 2])

In [192]: A[:,:,0]
Out[192]: 
array([[ 75, 160, 110,  29,  77, 198,  78],
       [237,  39, 219, 184,  73, 149, 144],
       [138, 148, 243, 160, 165, 125,  17],
       [155, 157, 110, 175,  91, 216,  61],
       [101,   5, 209,  98, 212,  44,  63],
       [213, 155,  96, 160, 193, 185, 157]])

In [193]: A[:,:,1]
Out[193]: 
array([[201, 223,   7, 140,  98,  41, 167],
       [139, 247, 134,  17,  74, 216,   0],
       [ 44,  28,  26, 182,  45,  24,  34],
       [178,  29, 233, 146, 157, 230, 173],
       [111, 220, 234,   6, 246, 218, 149],
       [200, 101,  23, 116, 166, 199, 233]])

2)输出:

In [194]: out
Out[194]: 
array([[[ 39, 219],
        [148, 243],
        [157, 110]],

       [[ 44,  28],
        [178,  29],
        [111, 220]]])