【问题标题】:Shuffle matrix without the shuffle() method [duplicate]没有 shuffle() 方法的随机矩阵[重复]
【发布时间】:2021-05-09 02:28:43
【问题描述】:

我需要取一个矩阵:

m = [[1, 2],
     [3, 4]]

然后随机播放,我一直在这样做:

m[0][0], m[0][1], m[1][0], m[1][1] = m[1][0], m[0][0], m[1][1], m[0][1] # or some other combination 

我不希望它是随机的,因为我希望能够反转它,虽然我不介意使用 2x2 矩阵执行上述操作,但我需要使用 4x4 或更大的矩阵来执行此操作,并且不要'不想对所有这些索引进行硬编码。

我也不想只切换行,例如:m[0], m[1] = m[1], m[0],而是单独的值,例如 m[0][1]m[1][0]

【问题讨论】:

  • 你想旋转矩阵吗?
  • 能否请您说明您这样做的原因,以便我们避免XY problem
  • 我正在制作一个简单的加密算法来取乐,并且正在寻找一种对矩阵进行洗牌的方法。
  • 不,我已经在使用它了。我正在寻找一种方法来打乱各个索引而不把它们全部写出来
  • 几乎,但同样,我不想更改行,而是要交换单个值。

标签: python matrix


【解决方案1】:

您可以随机播放“扁平化”索引。在 2x2 矩阵的情况下,“扁平化”是指索引 0[0][0]1[0][1]2[1][0]3[1][1]。通常对于具有c 列的矩阵,索引n 等价于[n//c][n%c]

改组后的索引(从0#rows * #columns 的数字)用作新矩阵的索引。 IE。 replace_indices = [3, 1, 0, 2] 意味着在混洗矩阵中,第 0 个索引 ([0][0]) 将取自原始矩阵的第 3 个索引 ([1][1])。以此类推:

from random import shuffle

m = ...

rows = len(m)
cols = len(m[0])

replace_indices = list(range(rows * cols))
shuffle(replace_indices)

shuffled_m = [[0] * cols for c in range(rows)]

for idx, sidx in enumerate(replace_indices):
    shuffled_m[idx//rows][idx%rows] = m[sidx//rows][sidx%rows]

现在要取消洗牌,您可以使用相同的replace_indices,但反过来:

unshuffled_m = [[0] * cols for c in range(rows)]

for idx, sidx in enumerate(replace_indices):
    unshuffled_m[sidx//rows][sidx%rows] = shuffled_m[idx//rows][idx%rows]

换句话说,replace_indices 是您加密的对称密钥。

【讨论】:

  • 那么你介意解释一下这里发生了什么吗?谢谢
  • 将尝试在答案中澄清它
【解决方案2】:

这对于 numpy 数组来说似乎是一个有趣的练习。我的解决方案非常冗长,但我希望它有助于说明每个步骤。

import numpy as np
import random


in_data = [[10,20,30,40],
            [51,61,71,81],
            [92,102,112,122],
            [133,143,153,163]]

array = np.array(in_data)  # Create array
print('Start array:\n', array)

old_shape = array.shape  # Preserve shape
long_array = np.reshape(array, array.size)  # turn it into a 1xN vector
print('long_array: ', long_array)


index = np.arange(0, array.size) # Create a simple 0-N index
print('index: ', index)
random.shuffle(index)  # Shuffle the index
print('shuffled index: ', index)

long_array = long_array[index]  # Apply shuffled index to the data array
print('shuffled long array: ', long_array[index])

shuffled_array = long_array.reshape(old_shape) # Create the 4x4 shape using the old_shape

print('reshaped shuffled array:\n', shuffled_array)

### UNSHUFFLING
# Generate a new linear index and sort the shuffled index to obtain a reverse sort
new = np.vstack([index, np.arange(0,len(index))])
new = new.T

unshuffled_index = new[new[:,0].argsort()].T[1,:]  # Sort the shuffled_index column
print("unshuffled_index: ", unshuffled_index)

# Condensed reshape, re-index, re-shape of the shuffled data
orig = np.reshape(np.reshape(shuffled_array, array.size)[unshuffled_index], old_shape)


print('original data:\n', orig)

如果我可以避免重新整形为 1xN 和/或有更聪明的方法来扭转洗牌,这会更干净。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 2019-08-23
    • 2019-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多