有条件的 Numpy 洗牌
Conditional Numpy shuffling
问题
假设您有一个这样的结构化 np.array
:
first_array = np.array([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9])
并且您想创建一个新的 np.array
大小相同,但打乱了顺序。
例如
second_array = np.random.shuffle(first_array)
second_array
# np.array([3, 2, 9, 5, 6, 1, 1, 6, 9, 7, 8, 5, 2, 7, 8, 3, 4, 4])
到目前为止,还不错。然而,随机洗牌导致一些重复项彼此非常接近,这是我试图避免的事情。
问题
我如何打乱这个数组,使整数顺序是伪随机的,但每个副本都有很高的概率彼此相距很远?这个问题有更具体的术语吗?
这比 numpy
更像是一个算法问题。一种天真的方法是用最小目标间距 (spacing_condition
) 拆分数组,数字应该至少相距那么远。
import numpy as np
first_array = np.array([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9])
spacing_condition = 3
subarrays = np.split(first_array, spacing_condition)
下一步是从 subarrays
中按顺序选择,这将保证 spacing condition
,并从该子数组中删除选择。
但是,对于大型数组,这最后两步的简单循环会很慢。在一个天真的实现之后,种子只是为了复制。
np.random.seed(42)
def choose_over_spacing(subarrays):
choices = []
new_subarrays_ = []
subarray_indices = np.arange(len(subarrays[0]))
for subarray in subarrays:
index_to_choose = np.random.choice(subarray_indices, 1)[0]
number_choice = subarray[index_to_choose]
choices.append(number_choice)
new_subarray = np.delete(subarray, index_to_choose)
new_subarrays_.append(new_subarray)
return choices, new_subarrays_
all_choices = []
for _ in np.arange(len(subarrays[0])):
choices, subarrays = choose_over_spacing(subarrays)
all_choices = all_choices + choices
检查结果,我们看到我们保证重复的数字至少相隔 3 个数字,因为我们使用 spacing_condition
条件,只要初始拆分有效,就可以选择不同的间距条件。
[2, 6, 8, 3, 6, 7, 2, 5, 9, 3, 4, 9, 1, 4, 8, 1, 5, 7]
问题
假设您有一个这样的结构化 np.array
:
first_array = np.array([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9])
并且您想创建一个新的 np.array
大小相同,但打乱了顺序。
例如
second_array = np.random.shuffle(first_array)
second_array
# np.array([3, 2, 9, 5, 6, 1, 1, 6, 9, 7, 8, 5, 2, 7, 8, 3, 4, 4])
到目前为止,还不错。然而,随机洗牌导致一些重复项彼此非常接近,这是我试图避免的事情。
问题
我如何打乱这个数组,使整数顺序是伪随机的,但每个副本都有很高的概率彼此相距很远?这个问题有更具体的术语吗?
这比 numpy
更像是一个算法问题。一种天真的方法是用最小目标间距 (spacing_condition
) 拆分数组,数字应该至少相距那么远。
import numpy as np
first_array = np.array([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9])
spacing_condition = 3
subarrays = np.split(first_array, spacing_condition)
下一步是从 subarrays
中按顺序选择,这将保证 spacing condition
,并从该子数组中删除选择。
但是,对于大型数组,这最后两步的简单循环会很慢。在一个天真的实现之后,种子只是为了复制。
np.random.seed(42)
def choose_over_spacing(subarrays):
choices = []
new_subarrays_ = []
subarray_indices = np.arange(len(subarrays[0]))
for subarray in subarrays:
index_to_choose = np.random.choice(subarray_indices, 1)[0]
number_choice = subarray[index_to_choose]
choices.append(number_choice)
new_subarray = np.delete(subarray, index_to_choose)
new_subarrays_.append(new_subarray)
return choices, new_subarrays_
all_choices = []
for _ in np.arange(len(subarrays[0])):
choices, subarrays = choose_over_spacing(subarrays)
all_choices = all_choices + choices
检查结果,我们看到我们保证重复的数字至少相隔 3 个数字,因为我们使用 spacing_condition
条件,只要初始拆分有效,就可以选择不同的间距条件。
[2, 6, 8, 3, 6, 7, 2, 5, 9, 3, 4, 9, 1, 4, 8, 1, 5, 7]