本文介绍一个高效、可复用的 Python 函数,用于生成 n 行 m 列的二值矩阵,精确控制其中值为 1 的元素比例(即密度 d),支持整数密度(绝对个数)与浮点密度(相对比例)两种语义。
本文介绍一个高效、可复用的 python 函数,用于生成 n 行 m 列的二值矩阵,精确控制其中值为 1 的元素比例(即密度 d),支持整数密度(绝对个数)与浮点密度(绝对个数)两种语义。
在科学计算、模拟实验或机器学习数据生成中,常需构造具有特定稀疏度的二值矩阵。原始代码存在逻辑冗余(如嵌套循环误用、未使用密度参数)、效率低下(重复采样可能冲突)且语义模糊(d 是比例还是总数?)。以下提供健壮、清晰、可扩展的实现方案。
✅ 推荐实现(支持比例与整数密度)
import random
def create_matrix(n, m, d):
"""
创建 n×m 的 0-1 矩阵,其中 1 的密度为 d。
参数:
n (int): 行数
m (int): 列数
d (float or int): 密度;若 0 ≤ d ≤ 1 → 视为比例(如 d=0.3 表示 30% 为 1);
若 d > 1 → 视为期望的 1 的总个数(向下取整,不超过 n*m)
返回:
list[list[int]]: n 行 m 列的二维列表,仅含 0 和 1
"""
total_cells = n * m
# 解析密度:统一转换为整数个数 k
if isinstance(d, float) and 0.0 <= d <= 1.0:
k = int(round(d * total_cells)) # 四舍五入确保更接近目标比例
elif isinstance(d, int) and 0 <= d <= total_cells:
k = d
else:
raise ValueError(f"d must be a float in [0,1] or an integer in [0, {total_cells}]")
# 初始化全零矩阵
matrix = [[0] * m for _ in range(n)]
# 高效无冲突采样:随机选择 k 个不重复位置置 1
positions = random.sample(range(total_cells), k)
for idx in positions:
row, col = divmod(idx, m) # 将一维索引映射为二维坐标
matrix[row][col] = 1
return matrix✅ 使用示例
# 示例1:4×5 矩阵,30% 为 1 → 期望约 6 个 1
mat1 = create_matrix(4, 5, 0.3)
print("Density 0.3:", mat1)
# 输出类似:[[0, 1, 0, 0, 1], [0, 0, 1, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 1, 0]]
# 示例2:指定恰好 7 个 1
mat2 = create_matrix(4, 5, 7)
print("Exactly 7 ones:", mat2)
# 示例3:全零或全一边界情况
print("All zeros:", create_matrix(3, 3, 0)) # [[0,0,0],[0,0,0],[0,0,0]]
print("All ones:", create_matrix(2, 4, 1.0)) # [[1,1,1,1],[1,1,1,1]]⚠️ 关键注意事项
- 避免重复采样:原答案中 while + if/else 循环在高密度时效率骤降(概率性重试),而 random.sample() 保证 O(k) 时间复杂度且无冲突;
- 密度语义明确:本实现兼容比例(0.0–1.0)和绝对数量(int),并做严格校验,防止越界;
- 可重现性:如需结果可复现,请在调用前设置 random.seed(42);
- 内存友好:直接构建列表,无需中间数组或 NumPy 依赖(若需高性能大规模矩阵,可替换为 numpy.random.choice 配合 np.zeros(...).ravel())。
该函数简洁、鲁棒、符合直觉,可直接集成至数据预处理流水线或仿真系统中。

















