Python Numpy 2D数组在行和非列之间移动元素

Python Numpy 2D数组在行和非列之间移动元素,python,arrays,numpy,shuffle,Python,Arrays,Numpy,Shuffle,我有以下二维数组: seq_length = 5 x = np.array([[0, 2, 0, 4], [5,6,7,8]]) x_repeated = np.repeat(x, seq_length, axis=1) [[0 0 0 0 0 2 2 2 2 2 0 0 0 0 0 4 4 4 4 4] [5 5 5 5 5 6 6 6 6 6 7 7 7 7 7 8 8 8 8 8]] 我想根据seq_length将x_repeated中的所有项混洗在一起 例如,可能的洗牌: [[0

我有以下二维数组:

seq_length = 5
x = np.array([[0, 2, 0, 4], [5,6,7,8]])
x_repeated = np.repeat(x, seq_length, axis=1)


[[0 0 0 0 0 2 2 2 2 2 0 0 0 0 0 4 4 4 4 4]
 [5 5 5 5 5 6 6 6 6 6 7 7 7 7 7 8 8 8 8 8]]
我想根据
seq_length
x_repeated
中的所有项混洗在一起

例如,可能的洗牌:

[[0 0 0 0 0 6 6 6 6 6 0 0 0 0 0 8 8 8 8 8]
 [5 5 5 5 5 2 2 2 2 2 7 7 7 7 7 4 4 4 4 4]]

谢谢

您可以这样做:

import numpy as np

seq_length = 5
x = np.array([[0, 2, 0, 4], [5, 6, 7, 8]])

swaps = np.random.choice([False, True], size=4)

for swap_index, swap in enumerate(swaps):
    if swap:
        x[[0, 1], swap_index] = x[[1, 0], swap_index]

x_repeated = np.repeat(x, seq_length, axis=1)
您还可以依赖
True
非零这一事实,并将
for
替换为:

for swap_index in swaps.nonzero()[0]:
    x[[0, 1], swap_index] = x[[1, 0], swap_index]

关键是我在
np.repeat
调用之前进行了洗牌/交换,这比之后进行更有效(同时满足需要交换的值序列的要求)。具有相同值的每对序列有50%的机会被交换。

您可以这样做:

import numpy as np

seq_length = 5
x = np.array([[0, 2, 0, 4], [5, 6, 7, 8]])

swaps = np.random.choice([False, True], size=4)

for swap_index, swap in enumerate(swaps):
    if swap:
        x[[0, 1], swap_index] = x[[1, 0], swap_index]

x_repeated = np.repeat(x, seq_length, axis=1)
您还可以依赖
True
非零这一事实,并将
for
替换为:

for swap_index in swaps.nonzero()[0]:
    x[[0, 1], swap_index] = x[[1, 0], swap_index]
关键是我在
np.repeat
调用之前进行了洗牌/交换,这比之后进行更有效(同时满足需要交换的值序列的要求)。具有相同值的每对序列交换的几率为50%。

import random
将numpy作为np导入
序号长度=5
x=np.数组([[0,2,0,4],[5,6,7,8]]
x_重复=np重复(x,序列长度,轴=1)
cnt=0
第一行=真
在(0,4)范围内的x的参考值为1=[(λx:x_重复[0][seq_length*x])(x)]#[0,2,0,4]
在(0,4)范围内的x的参考值为2=[(λx:x_重复[1][seq_length*x])(x)#[5,6,7,8]
nlist=[]
当cnt<8时:
第一行=整数(非第一行)
如果第一行==0:
索引=random.randint(0,len(参考1)-1)
num=ref_lst_1[索引]
#打印(“参考1:,参考1”)
参考1.pop(索引)
如果第一行==1:
索引=random.randint(0,len(参考2)-1)
num=ref_lst_2[索引]
#打印(“参考第2页:”,参考第2页)
参考2.pop(索引)
nlist=nlist+[num]*序号长度
cnt+=1
打印(nlist)
"""[0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 
0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7]
"""
narray=np.array([nlist[0:20],nlist[20:40]))
打印(narray)
"""[[0 0 0 0 0 5 5 5 5 5 4 4 4 4 4 8 8 8 8 8]
[0 0 0 0 0 6 6 6 6 6 2 2 2 2 2 7 7 7 7 7]]"""
随机导入
将numpy作为np导入
序号长度=5
x=np.数组([[0,2,0,4],[5,6,7,8]]
x_重复=np重复(x,序列长度,轴=1)
cnt=0
第一行=真
在(0,4)范围内的x的参考值为1=[(λx:x_重复[0][seq_length*x])(x)]#[0,2,0,4]
在(0,4)范围内的x的参考值为2=[(λx:x_重复[1][seq_length*x])(x)#[5,6,7,8]
nlist=[]
当cnt<8时:
第一行=整数(非第一行)
如果第一行==0:
索引=random.randint(0,len(参考1)-1)
num=ref_lst_1[索引]
#打印(“参考1:,参考1”)
参考1.pop(索引)
如果第一行==1:
索引=random.randint(0,len(参考2)-1)
num=ref_lst_2[索引]
#打印(“参考第2页:”,参考第2页)
参考2.pop(索引)
nlist=nlist+[num]*序号长度
cnt+=1
打印(nlist)
"""[0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 
0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7]
"""
narray=np.array([nlist[0:20],nlist[20:40]))
打印(narray)
"""[[0 0 0 0 0 5 5 5 5 5 4 4 4 4 4 8 8 8 8 8]
[0 0 0 0 0 6 6 6 6 6 2 2 2 2 2 7 7 7 7 7]]"""

通过以下方式解决了此问题:

items_count = x.shape[-1]    
swap_flags = np.repeat(np.random.choice([0, 1], size=items_count), single_item_length)
给出:

[1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1]

for idx, flag in enumerate(swap_flags):
    if flag:
        x_repeated[0,idx], x_repeated[1,idx] = x_repeated[1,idx], x_repeated[0,idx]
结果:

[[5 5 5 5 5 6 6 6 6 6 0 0 0 0 0 8 8 8 8 8]
 [0 0 0 0 0 2 2 2 2 2 7 7 7 7 7 4 4 4 4 4]]

仍然没有那么优雅的
numpy
方式。

通过以下方式解决了这个问题:

items_count = x.shape[-1]    
swap_flags = np.repeat(np.random.choice([0, 1], size=items_count), single_item_length)
给出:

[1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1]

for idx, flag in enumerate(swap_flags):
    if flag:
        x_repeated[0,idx], x_repeated[1,idx] = x_repeated[1,idx], x_repeated[0,idx]
结果:

[[5 5 5 5 5 6 6 6 6 6 0 0 0 0 0 8 8 8 8 8]
 [0 0 0 0 0 2 2 2 2 2 7 7 7 7 7 4 4 4 4 4]]
仍然没有那么优雅的方式。

以下是我的尝试:

def randomize_blocks(arr):
  """ Shuffles an n-dimensional array given consecutive blocks of numbers.
  """
  groups = (np.diff(arr.ravel(), prepend=0) != 0).cumsum().reshape(arr.shape)
  u, c = np.unique(groups, return_counts=True)
  np.random.shuffle(u)
  o = np.argsort(u)
  return arr.ravel()[np.argsort(np.repeat(u, c[o]))].reshape(arr.shape)

细分
首先,我们要分组

groups = (np.diff(arr.ravel(), prepend=0) != 0).cumsum().reshape(arr.shape)

然后,我们得到每个组的唯一和计数

u, c = np.unique(groups, return_counts=True)

最后,我们
shuffle
我们的唯一组,重建数组,并使用
argsort
对被洗牌的唯一组重新排序

o = np.argsort(u)
arr.ravel()[np.argsort(np.repeat(u, c[o]))].reshape(arr.shape)

用法示例:

>>> randomize_blocks(arr)
array([[0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5],
       [7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6]])

以下是我的尝试:

def randomize_blocks(arr):
  """ Shuffles an n-dimensional array given consecutive blocks of numbers.
  """
  groups = (np.diff(arr.ravel(), prepend=0) != 0).cumsum().reshape(arr.shape)
  u, c = np.unique(groups, return_counts=True)
  np.random.shuffle(u)
  o = np.argsort(u)
  return arr.ravel()[np.argsort(np.repeat(u, c[o]))].reshape(arr.shape)

细分
首先,我们要分组

groups = (np.diff(arr.ravel(), prepend=0) != 0).cumsum().reshape(arr.shape)

然后,我们得到每个组的唯一和计数

u, c = np.unique(groups, return_counts=True)

最后,我们
shuffle
我们的唯一组,重建数组,并使用
argsort
对被洗牌的唯一组重新排序

o = np.argsort(u)
arr.ravel()[np.argsort(np.repeat(u, c[o]))].reshape(arr.shape)

用法示例:

>>> randomize_blocks(arr)
array([[0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5],
       [7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6]])


谢谢你的回答,但你没有回答。您在行和列之间进行了无序移动。我问的只是在两行之间移动。谢谢你的回答,但你没有回答。您在行和列之间进行了无序移动。我问的是只在两行之间洗牌。