从给定的元素列表生成随机的numpy数组,每个元素至少重复一次

时间:2018-12-25 05:14:46

标签: python algorithm numpy random

我想在重新采样后从给定的numpy(例如output_list)创建一个数组(例如input_list),以使input_list中的每个元素至少存在于output_list中一旦。 output_list的长度将始终> input_list.的长度

我尝试了几种方法,我正在寻找一种更快的方法。不幸的是,numpy的{​​{1}}不保证至少存在一个元素。

第1步:生成数据

random.choice

选项1: 让我们尝试以概率分布均匀的import string import random import numpy as np size = 150000 chars = string.digits + string.ascii_lowercase input_list= [ "".join( [random.choice(chars) for i in range(5)] ) for j in range(dict_data[1]['unique_len'])] 的{​​{1}}。

numpy

这引起了断言:

  

输出列表的元素少于输入列表

选项2 让我们将随机数填充到random.choice,然后将其随机播放。

output_list = np.random.choice(
    input_list,
    size=output_size,
    replace=True,
    p=[1/input_list.__len__()]*input_list.__len__()
    )
assert set(input_list).__len__()==set(output_list).__len__(),\
    "Output list has fewer elements than input list"

尽管这不会引起任何断言,但我正在寻找一种比此算法或使用input_list内置函数的解决方案更快的解决方案。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

lenI为输入列表长度,lenO为输出列表长度。

1)从源列表中进行lenO - lenI次均匀随机选择的迭代

2)然后将所有输入列表附加到输出列表的末尾

3)然后进行lenI的Fisher–Yates迭代以重新均匀分布最后一个元素。

import random
src = [1, 2, 3, 4]
lD = 10
lS = len(src)
dst = []
for _ in range(lD - lS):
    dst.append(src[random.randint(0, lS-1)])
dst.extend(src)
print(dst)
for i in range(lD - 1, lD - lS - 1, -1):
    r = random.randint(0, lD - 1)
    dst[r], dst[i] = dst[i], dst[r]
print(dst)

>>[4, 3, 1, 3, 4, 3, 1, 2, 3, 4]
>>[4, 3, 1, 3, 4, 3, 1, 3, 4, 2]

这是线性复杂的方法。