python - 无替换的多个随机数序列
问题描述
在numpy中,我可以使用代码
from numpy.random import default_rng
rng = default_rng()
M, N, n = 10000, 1000, 3
rng.choice(np.arange(0, N), size=n, replace=False)
从 0 到 9 得到三个随机样本而不进行替换。
我想获得数千个这样的随机序列。这样做的正确方法是什么?我知道我能做到
np.array([rng.choice(np.arange(0, N), size=(n,), replace=False) for i in range(0, M)])
但我想知道是否有更有效的方法来使用numpy
.
在这个答案中,推荐以下方式
np.argsort(rng.random((M,N)),axis=1)[:, :n]
这是超快和优雅的。然而,成本规模就像我希望实现N x M
的那样。n x M
还有其他方法吗?
解决方案
方法#1
对于N
>> n
,我们可以使用带有掩码的迭代方法,以便在每次迭代时,我们每行选择一个先前未选择的元素。实现看起来像这样 -
R = np.arange(M)
mask = np.ones((M,N), dtype=bool)
idx = np.random.randint(0,N,(M))
mask[R,idx] = 0
for i in range(1,n):
lim = N-i
m2 = np.ones((M,lim), dtype=bool)
idx2 = np.random.randint(0,lim,(M))
m2[R,idx2] = 0
mask[mask] = m2.ravel()
out = np.nonzero(~mask)[1].reshape(-1,n)
如果您需要对每行的数字进行随机化,请使用问题帖子中链接的 rand-trick:
out = np.take_along_axis(out, np.random.rand(M,n).argsort(1), axis=1)
如果常量数组创建m2
困扰您,请在循环前初始化后重新使用,同时保持其余代码相同 -
m2 = np.ones((M,N-1), dtype=bool)
for i in range(1,n):
lim = N-i
idx2 = np.random.randint(0,lim,(M))
m2[R,idx2] = 0
mask[mask] = m2.ravel()
m2[R,idx2] = 1
m2 = m2[:,:-1]
方法 #2与 类似Approach #1
,但初始化部分完成了为每行设置 unqiue 随机数的大部分工作。额外的while
迭代部分负责处理无法分配唯一行的行。使用N
>> n
,我们几乎不需要迭代。实现看起来像这样 -
# https://stackoverflow.com/a/51915131/ @Divakar
def random_num_per_grp(L):
# For each element in L pick a random number within range specified by it
r1 = np.random.rand(np.sum(L)) + np.repeat(np.arange(len(L)),L)
offset = np.r_[0,np.cumsum(L[:-1])]
return r1.argsort()[offset] - offset
R = np.arange(M)
mask = np.ones((M,N), dtype=bool)
idx = np.random.randint(0,N,(M,n))
mask[R[:,None],idx] = 0
rows_notdone = mask.sum(1)!=N-n
while np.any(rows_notdone):
idx0 = random_num_per_grp(mask[rows_notdone].sum(1))
steps = np.r_[0,mask.sum(1).cumsum()[:-1]]
flat_idx0 = steps[rows_notdone] + idx0
m2 = np.ones(mask.sum(), dtype=bool)
m2[flat_idx0] = 0
mask[mask] = m2
rows_notdone = mask.sum(1)!=N-n
out = np.nonzero(~mask)[1].reshape(-1,n)
推荐阅读
- sql-server - 为什么删除语句会影响附加行?
- mysql - 无法创建mysql存储过程
- android - 与 AdMob 的内部跟踪链接
- uwp - 尝试读取 UWP C++ 时找不到文件
- html - 如何将内联块相对于它们的前一个定位在一行中?
- javascript - 为什么我在对象中使用箭头函数时出现错误“不是函数”
- ios - 将相机移动到底部 GMSMapView IOS
- java - 是否可以在没有 GUI 的情况下浏览存储访问框架?
- ios - UITabbar 图像向上向下移动
- c# - .NET 4.7.2 项目中的 .NET Standard 2.0 库引用优于 .NET 4.5.1