首页 > 解决方案 > 从给定的元素列表生成随机 numpy 数组,每个元素至少重复一次

问题描述

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

我尝试了一些方法,我正在寻找一种更快的方法。不幸的是,numpy'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's 。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"

这引发了断言:

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

选项 2 让我们将随机数填充到input_list然后随机播放。

output_list = np.concatenate((np.array(input_list),np.random.choice(
    input_list,
    size=output_size-input_list.__len__(),
    replace=True,
    p=[1/input_list.__len__()]*input_list.__len__()
)),axis=None)

np.random.shuffle(output_list)
assert set(input_list).__len__()==set(output_list).__len__(),\
    "Output list has fewer elements than input list"

虽然这不会引发任何断言,但我正在寻找比这更快的解决方案,无论是算法上还是使用numpy的内置函数。

谢谢你的帮助。

标签: pythonalgorithmnumpyrandom

解决方案


LetlenI是输入列表长度,lenO是输出列表长度。

1)lenO - lenI从源列表中进行统一随机选择的迭代

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

3)然后进行lenIFisher-Yates shuffle的迭代以均匀分布最后的元素。

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]

这是具有线性复杂度的方法。


推荐阅读