python - Numpy 随机选择,每个元素的重复时间有限
问题描述
给定N
元素0, ..., N-1
,以及一个指定每个元素数量的repeats
大小数组。N
我想知道随机选择size
元素的最快方法是什么?输出是一个大小数组,N
指示每个元素的所选数量。sum(output) == size
.
例如,
def choice(repeats, size): ...
choice([100, 200, 300, 400, 500], 5)
# a random output: array([1, 0, 2, 1, 1])
请参阅当前解决方案的答案。
我想知道是否有避免分配元素option
数组的方法?sum(repeats)
与不正确的实现但没有分配相比,当有很多元素时,速度差异大约为 20 倍:
def choice_wrong(repeats, size):
chosen = np.random.choice(len(repeats), size, p=repeats/np.sum(repeats))
return np.bincount(chosen, minlength=len(repeats))
%timeit choice([10000, 20000, 30000, 40000, 50000], 5000)
# 2.3 ms ± 7.47 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit choice_wrong([10000, 20000, 30000, 40000, 50000], 5000)
# 129 µs ± 822 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
解决方案
也许这对其他人有用:random.sample 选择多个元素而不重复。因此,如果您根据限制创建一个包含重复元素的列表并使用 random.sample() ,那么您将获得有限重复的随机选择。
一般示例:
size = 5
RepetitionLimit = 3
>>> originalList = [1,2,3]
>>> listWithRep = [i for i in originalList for j in range(RepetitionLimit)]
>>> listWithRep
[1,1,1,2,2,2,3,3,3]
>>> outputList = random.sample(listWithRep , size)
>>> outputList
[1,1,1,2,3]
在这个问题的情况下,它会是这样的(虽然它类似于你的解决方案@Peter O.):
RepetitionLimit = [100, 200, 300, 400, 500]
def choice(repeats, size):
chosen = random.sample([idx for idx, elem in enumerate(repeats) for i in range(elem)], size)
return [chosen.count(i) for i in range(len(repeats))]
choice(RepetitionLimit, 5)
# if chosen is [3, 3, 3, 4, 3] for example then result is [0, 0, 0, 4, 1]
推荐阅读
- python-3.x - 在主词典中附加词典对象
- html - 创建一个新的空白行元素而不从其上方的行传递值
- python - 如何在 python 中将 datetime.date 对象转换为字符串
- ibm-cloud - IBM Natural Language Understanding - 返回页面标题
- reactjs - 在 reactjs 中添加更多点击时以相反的顺序呈现 JSX 模板
- postgresql - 我想根据 Postgresql 上的数据时间在我的表中添加一列,显示数据中的周数
- python-3.x - 使用 tkinter 从条目小部件将输入打印到文本框
- c++ - 提升精神 x3 错误处理与预期
- excel - 如何修复此 Excel VBA 代码以导入空单元格
- ada - (Ada 2012)编译时错误“预期私有类型...找到复合类型”