Python 的 random
模块具有用于替换采样的 random.choices
和用于不替换采样的 random.sample
。尽管 random.choices 接受 numpy 数组并返回相对于第一个维度随机选择的元素的列表,但 random.sample 会引发
TypeError: Population must be a sequence or set. For dicts, use list(d).
另一方面,random.choices
不会接受集合,从而提高
TypeError: 'set' object does not support indexing.
我很好奇的是,这是否是一个疏忽,或者是否存在将 random.sample
限制为序列和集合而同时 random.choices
受到限制的根本原因尽管功能具有非常相似的用途,但支持索引的对象。
附注如果有人想知道如何对 ndarray 进行采样,numpy.random.choice
对带替换和不带替换的 1darray 进行采样,并且可以使用高级索引对任何维度有效地采样高维数组,其中该维度的索引是使用 numpy.random.choice
最佳答案
random.sample
尝试 check它的参数是否是 collections.abc.Sequence
的实例或collections.abc.Set
。这是一个比许多人认为的更不可靠的检查,因为它只检测具体继承自这些 ABC 或显式注册的类型。 numpy.ndarray
不从这些类继承并且未注册。
没有检查,或者如果您明确执行 collections.abc.Sequence.register(numpy.ndarray)
, random.sample
handle numpy.ndarray
很好。
顺便说一下,numpy.random.choice
与 replace=False
效率低得离谱,生成 entire permutation输入只是为了抽取一个小样本。这是longstanding issue由于自然修复会改变使用 seed
的人的结果,因此该问题尚未得到解决。 。从 NumPy 1.17 开始,您应该使用新的 Generator API:
rng = numpy.random.default_rng()
result = rng.choice(input, size=whatever, replace=False)
生成器 API 不受旧 API 向后兼容性保证的约束,因此他们可以自由更改算法。如果您坚持使用旧的 NumPy,那么根据参数,使用 random.sample
通常会更快。 ,或者手动计算样本,而不是使用 numpy.random.choice
与 replace=False
.
关于python - 为什么 random.sample 不能处理 numpy 数组,而 random.choices 可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54058718/