对numpy矩阵的行进行交织,生成置换方案

时间:2018-10-19 17:00:41

标签: python numpy

我有一个矩阵,我想根据下面描述的以下方案按行随机排序:

我们有矩阵a

import numpy as np
np.random.seed(0)
low = -5
high = 5

num_frames = 2
other_value = 3
dim1 = num_frames * other_value
dim2 = 5
a_shape = (dim1, dim2)
a = np.random.random_integers(low, high, size=a_shape)
print(a)

[[ 0 -5 -2 -2  2]
 [ 4 -2  0 -3 -1]
 [ 2  1  3  3  5]
 [-4  1  2  2  3]
 [-4  0  4  3  4]
 [-1 -2 -5 -2  0]]

我们想将行分成num_frames组。因此,对于2帧的矩阵a,我们的拆分看起来像这样:

[[ 0 -5 -2 -2  2]
 [ 4 -2  0 -3 -1]
 [ 2  1  3  3  5]

 [-4  1  2  2  3]
 [-4  0  4  3  4]
 [-1 -2 -5 -2  0]]

然后,我们要交织每一帧的行,因此排列将指定为[0, 3, 1, 4, 2, 5],其中这些数字是行索引。

对于a,这将为我们提供一个看起来像这样的矩阵:

[[ 0 -5 -2 -2  2]
[-4  1  2  2  3]
[ 4 -2  0 -3 -1]
[-4  0  4  3  4]
[ 2  1  3  3  5]
[-1 -2 -5 -2  0]]

如果我们有3帧,但行数相同(因此other_value=2),则我们的排列将是[0, 2, 4, 1, 3, 5],得到一个矩阵:

 [[ 0 -5 -2 -2  2]
 [ 2  1  3  3  5]
 [-4  0  4  3  4]
 [ 4 -2  0 -3 -1]     
 [-4  1  2  2  3]
 [-1 -2 -5 -2  0]]

我不太高兴的是:

对于任意大小的矩阵和帧数,什么样的方式可以生成正确的排列?假设每个帧(或dim1 % num_frames = 0)中的行数总是相同。

一种置换行的方法是下面的代码,但是我不确定如何获取置换。

b = a.copy()
perm = [0, 3, 1, 4, 2, 5]
b[[0, 1, 2, 3, 4, 5]] = a[perm]
print(b)

3 个答案:

答案 0 :(得分:3)

这是使用np.reshapenp.transpose做您想要的事情的一种功能:

def interleave_frames(a, num_frames):
    if len(a) % num_frames != 0: raise ValueError
    frame_size = len(a) // num_frames
    out = np.reshape(a, (num_frames, frame_size, -1))
    out = np.transpose(out, (1, 0, 2))
    return np.reshape(out, (len(a), -1))

测试:

import numpy as np

np.random.seed(0)
low = -5
high = 5
num_frames = 2
other_value = 3
dim1 = num_frames * other_value
dim2 = 5
a_shape = (dim1, dim2)
a = np.random.random_integers(low, high, size=a_shape)
print('Array:')
print(a)
print('Interleaved:')
print(interleave_frames(a, num_frames))

输出:

Array:
[[ 0 -5 -2 -2  2]
 [ 4 -2  0 -3 -1]
 [ 2  1  3  3  5]
 [-4  1  2  2  3]
 [-4  0  4  3  4]
 [-1 -2 -5 -2  0]]
Interleaved:
[[ 0 -5 -2 -2  2]
 [-4  1  2  2  3]
 [ 4 -2  0 -3 -1]
 [-4  0  4  3  4]
 [ 2  1  3  3  5]
 [-1 -2 -5 -2  0]]

编辑:

如果您仍然想获取索引,则可以使用相同的方法(重塑/转置/重塑):

print(np.arange(len(a)).reshape((num_frames, -1)).transpose().reshape(-1))
# [0 3 1 4 2 5]

答案 1 :(得分:1)

此循环逻辑应提供所需的排列:

a = [0, 1, 2, 3, 4, 5]

num_frames = 2
other_value = 3

new_list = []
for i in range(other_value):
    for j in range(i, len(a), other_value):
        new_list.append(j)

print new_list

答案 2 :(得分:1)

要获得排列,可以执行以下操作:

def perm(nb_rows, nb_frames):
    return [frame*nb_rows//nb_frames + row for row in range(nb_rows // nb_frames)      
                                           for frame in range(nb_frames)]

print(perm(6, 2))
# [0, 3, 1, 4, 2, 5]

print(perm(6, 3))
# [0, 2, 4, 1, 3, 5]

print(perm(20, 4))
# [0, 5, 10, 15, 1, 6, 11, 16, 2, 7, 12, 17, 3, 8, 13, 18, 4, 9, 14, 19]