Python随机采样详解:random与numpy的有放回与无放回实现

Elena
Elena
发布时间:2026-10-15| 3人浏览过
原创

本文深入解析Python中的随机采样机制,涵盖random模块与numpy库的核心函数。详细对比random.choice、random.choices(支持权重与有放回)及random.sample(无放回)的使用场景,并介绍基于Random实例的采样方法。同时解析numpy.random.choice的参数配置,包括权重、大小及替换选项,助你在机器学习数据预处理中精准控制采样逻辑。

Python及其扩展库Numpy内置了丰富的概率算法,既包含基础的随机采样功能,也涵盖多种经典概率分布的生成方式。本系列文章将重点介绍机器学习中常用的几类概率函数,首先从最基础的随机采样功能开始讲解。

1. random.choice

若仅需从序列中抽取单个样本,且假设所有样本被抽中的概率均等,可直接调用random.choice函数实现。


import random
res1 = random.choice([0, 1, 2, 3, 4])
print(res1) # 3

2. random.choices(有放回)

在实际应用中,往往需要抽取多个样本,并指定序列中各元素被抽中的不同概率。此时应使用random.choices函数,该函数支持有放回采样,即同一数据项可被多次抽取。其函数定义如下:


random.choices(population, weights=None, *, cum_weights=None, k=1)

population:指定待采样的目标序列。

weights:为每个样本设定的权重(相对权重),用于决定各样本被抽中的概率,例如传入[10, 0, 30, 60, 0]。

cum_weights:累积权重,相对权重[10, 0, 30, 60, 0]对应的累积权重为[10, 10, 40, 100, 100]。

以下示例展示从[0, 1, 2, 3, 4]中依据相对权重抽取3个样本的过程:


res2 = random.choices([0, 1, 2, 3, 4], weights=[10, 0, 30, 60, 0], k=3)
# 注意population不是关键字参数,在函数调用时不能写成population=[0,1,2,3,4]来传参
# 关于关键字参数和位置参数,可以参看我的博客《Python技法2:函数参数的进阶用法》https://www.cnblogs.com/orion-orion/p/15647408.html
print(res2) # [3, 3, 2]

以下示例展示从[0, 1, 2, 3, 4]中依据累积权重抽取3个样本的过程:


res3 = random.choices([0, 1, 2, 3, 4], cum_weights=[10, 10, 40, 100, 100], k=3)
print(res3) # [0, 3, 3]

需注意,weights与cum_weights不可同时传入参数,否则系统将抛出TypeError异常'Cannot specify both weights and cumulative weights'。

3. numpy.sample(无放回)

random.sample执行的是无放回采样,即每个元素仅能被抽取一次。若需进行无放回操作,必须使用random.sample。值得注意的是,该函数不支持定义样本权重。其函数原型如下:


random.sample(population, k, *, counts=None)¶

population:指定待采样的序列。

k:指定需要抽取的元素数量。

counts:当population为可重复集合时使用,用于定义集合中各元素的重复次数。例如sample(['red', 'blue'], counts=[4, 2], k=5)等价于sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5)。

以下示例展示对序列[0, 1, 2, 3, 4]进行无放回采样,抽取3次:


res3 = random.sample([0, 1, 2, 3, 4], k=3)
print(res3) # [3, 2, 1]

以下示例展示对可重复集合[0, 1, 1, 2, 2, 3, 3, 4]进行无放回采样,抽取3次:


res4 = random.sample([0, 1, 2, 3, 4], k=3, counts=[1, 2, 2, 2, 1])
print(res4) # [3, 2, 2]

若counts的长度与population序列长度不一致,系统将抛出异常ValueError:"The number of counts does not match the population"。

4.rng.choices 和 rng.sample

另一种有放回采样的实现方式源自论文[1]的代码[2],即先定义一个随机数生成器实例,再调用该实例的choices或sample方法。其使用方式与random.choice/random.sample函数一致。


rng_seed = 1234
rng = random.Random(rng_seed)
res5 = rng.choices(
     population=[0,1,2,3,4],
     weights=[0.1, 0, 0.3, 0.6, 0],
     k=3,
)
print(res5) # [3, 3, 0]

res6 = rng.sample(
     population=[0, 1, 2, 3, 4],
     k=3,
)
print(res6) # [4, 0, 2]

在论文[1]的实现代码[2]中,这两个函数被用于随机选择任务节点client:


def sample_clients(self):
        """
        sample a list of clients without repetition

        """
        rng_seed = (seed if (seed is not None and seed >= 0) else int(time.time()))
        self.rng = random.Random(rng_seed)

        if self.sample_with_replacement:
            self.sampled_clients = \
                self.rng.choices(
                    population=self.clients,
                    weights=self.clients_weights,
                    k=self.n_clients_per_round,
                )
        else:
            self.sampled_clients = self.rng.sample(self.clients, k=self.n_clients_per_round)

5. numpy.random.choices

若需按权重分布从序列中采样,也可采用numpy.random.choice实现。其函数原型如下:


random.choice(a, size=None, replace=True, p=None)

a:1-D array-like或int。若为1-D array-like,则从数组元素中抽取样本;若为int,则从np.arange(a)中抽取。

size:int或tuple of ints,可选。指定输出形状的大小,若指定形状为(m,n,k),则抽取m×n×k个样本。默认为None,即返回单一标量。

replace:boolean,可选。表示采样是否为有放回。若replace=True,则为有放回采样(值可被多次抽取);否则为无放回采样(值仅能抽取一次)。

p:1-D array-like,可选。表示a中各项被抽取的概率。若未指定,则假定a中各项服从均匀分布(即概率相同)。

以下示例展示从[0,1,2,3,4,5]中重复/不重复采样3次的情况:


import numpy as np
res1 = np.random.choice(5, 3, replace=True)
print(res1) # [1 1 4]

res2 = np.random.choice(5, 3, replace=False)
print(res2) # [2 1 4]

同样从[0,1,2,3,4,5]中重复/不重复采样3次,此处展示为每个样本设定不同概率的情况:


res3 = np.random.choice(5, 3, p=[0.1, 0, 0.3, 0.6, 0])
print(res3)  # [2 3 3]

res4 = np.random.choice(5, 3, replace=False, p=[0.1, 0, 0.3, 0.6, 0])
print(res4) # [3 2 0]

参考文献

https://github.com/omarfoq/FedEM

https://www.python.org/

https://numpy.org/

本文关于Python随机采样与概率分布的解析到此结束,更多Python相关内容可查阅本站往期文章或继续浏览后续文章,感谢支持。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。