最可靠的方法是使用numpy.random.Generator.choice:RNG需要先创建 = np.random.default_rng(seed)例子,再次调用rng.choice(arr, size, replace=False),性能优异,可复制,线程安全,不支持隐式多维输入,轴向抽样或平整必须手动处理。用
numpy.random.Generator.choice 这是目前最可靠的方式
NumPy 1.17+ 弃用了旧的 numpy.random.choice(来自全局 np.random 基于模块的推荐使用) Generator 新界面。默认情况下,没有放回抽样,底部使用 Fisher-Yates 变体洗牌,性能好,可复制,线程安全。
直接调用常见错误 np.random.choice(a, size, replace=False) —— 这在 NumPy ≥1.25 中会触发 DeprecationWarning,随机种子粒度无法控制。
- 必须先创建
Generator实例:rng = np.random.default_rng(seed=42) - 抽样时输入数组本身(而不是长度):
rng.choice(arr, size=10, replace=False),arr可以是 1D 数组或任何可能的索引序列 - 若
arr它是多维的,需要先展平或使用np.take+ 随机索引配合,choice不支持高维数组直接轴向无放回采样
当 size 接近 len(arr)(比如 > 70%),replace=False 内部会退化为洗牌后的切片(即先退化为洗牌后的切片) shuffle 整个数组再次取前 size (1)这将额外分配等长内存并修改原始数组副本。
如果你只想“打乱后取前” k 个”,更有效的方法是直接 shuffle 再切片:
立即学习“Python免费学习笔记(深入);
rng = np.random.default_rng(42) shuffled = arr.copy() rng.shuffle(shuffled) sample = shuffled[:k]
这样就避免了 choice 特别是在大数组和高比例采样中,中间索引映射费用很快 2–3 而且显式可控。
Python数据分析助手
为业务和科研数据的快速处理提供Python数据清理、统计分析和可视化建议。
下载 手动结构索引二维数组按行/列无放回抽样Generator.choice 只接受一维输入,不能直接写 rng.choice(matrix, axis=0, replace=False) —— 这会报错 ValueError: a must be 1-dimensional。
正确的方法是生成行/列索引,然后用高级索引提取:
- 按行抽样(随机选择) 5 行):
rows = rng.choice(matrix.shape[0], size=5, replace=False); sample = matrix[rows] - 按列抽样(随机选择) 3 列):
cols = rng.choice(matrix.shape[1], size=3, replace=False); sample = matrix[:, cols] - 注意:这里
choice作用于整数范围,而不是原始数组,因此不会触发复制整个数据的费用
replace 默认值和 seed 行为
老写法 np.random.choice(arr, 10) 默认 replace=True;而新 Generator.choice **没有默认 replace 值**,必须显式传参,否则报告 TypeError。
另外,np.random.seed() 全局影响所有后续调用,但是 default_rng(seed) 在多线程或单元测试中,这是一个局部实例,不相互干扰——这一点尤为关键。泄漏会导致随机污染。
最容易被忽视的是,如果原始逻辑依赖 np.random.choice 隐藏非一维数组 ravel 行为(如传入) list of lists),新界面将直接报错,必须提前报错 np.asarray(...).ravel()。