You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中按3×3块聚合缩小二进制矩阵并保留所有1?

二进制矩阵按3×3块聚合的实现方法

以下是几种针对需求的实现方案,核心逻辑均为判断每个3×3子块中是否存在1,存在则目标位置设为1,否则为0:

一、Python 实现

1. NumPy 高效向量化解法

利用NumPy的维度重塑和批量操作,适合处理大矩阵,效率极高:

import numpy as np

# 假设原矩阵为binary_matrix,形状(648, 2340),元素为0或1
binary_matrix = np.random.randint(0, 2, (648, 2340), dtype=np.uint8)

# 重塑维度:将原矩阵拆分为(216, 3, 780, 3)的块结构
blocked_matrix = binary_matrix.reshape(216, 3, 780, 3)
# 交换轴,让块的维度集中在最后两位:(216, 780, 3, 3)
blocked_matrix = blocked_matrix.transpose(0, 2, 1, 3)
# 对每个3×3块判断是否存在1,最后转换为uint8类型
result_matrix = np.any(blocked_matrix, axis=(2, 3)).astype(np.uint8)

逻辑说明:通过reshape和transpose将原矩阵划分成独立的3×3子块,再用np.any批量检查每个块内是否有1,直接得到结果矩阵。

2. 基于稀疏性的优化解法

由于原矩阵大部分是0、仅少量1,可只处理含1的位置,大幅减少计算量:

import numpy as np

binary_matrix = np.random.randint(0, 2, (648, 2340), dtype=np.uint8)
result_matrix = np.zeros((216, 780), dtype=np.uint8)

# 获取所有1的坐标
rows, cols = np.where(binary_matrix == 1)
# 计算每个1对应的目标块坐标
target_rows = rows // 3
target_cols = cols // 3
# 将这些目标位置设为1
result_matrix[target_rows, target_cols] = 1

逻辑说明:先定位所有1的位置,再映射到目标矩阵的对应块索引,直接标记这些块为1,其余保持0,适合稀疏矩阵场景。

3. 纯Python循环解法(适合理解逻辑,效率较低)

如果不依赖NumPy,可手动遍历每个子块:

# 假设原矩阵是列表的列表:binary_matrix = [[0,1,...], ...]
binary_matrix = [[0]*2340 for _ in range(648)]
result_matrix = [[0]*780 for _ in range(216)]

for i in range(216):
    for j in range(780):
        # 计算当前块在原矩阵的起始坐标
        start_row = i * 3
        start_col = j * 3
        # 遍历3×3块内的元素
        has_one = False
        for x in range(3):
            for y in range(3):
                if binary_matrix[start_row + x][start_col + y] == 1:
                    has_one = True
                    break
            if has_one:
                break
        result_matrix[i][j] = 1 if has_one else 0

二、C++ 实现(基于OpenCV)

利用OpenCV的矩阵操作,适合工程场景:

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    // 读取或创建原二进制矩阵,尺寸648×2340,类型CV_8U
    Mat binary_matrix(648, 2340, CV_8U);
    randu(binary_matrix, 0, 2); // 示例生成随机二进制矩阵

    Mat result_matrix(216, 780, CV_8U, Scalar(0));

    for (int i = 0; i < 216; ++i) {
        for (int j = 0; j < 780; ++j) {
            // 提取3×3子块
            Rect roi(j*3, i*3, 3, 3);
            Mat block = binary_matrix(roi);
            // 判断块内是否有非零元素(即1)
            if (countNonZero(block) > 0) {
                result_matrix.at<uchar>(i, j) = 1;
            }
        }
    }

    return 0;
}

三、MATLAB 实现

使用blockproc函数直接处理块:

% 原二进制矩阵,尺寸648×2340
binary_matrix = randi([0,1], 648, 2340);
% 定义块处理函数:判断块内是否有1
block_func = @(block_struct) any(block_struct.data(:)) * 1;
% 按3×3块处理,得到216×780的结果矩阵
result_matrix = blockproc(binary_matrix, [3 3], block_func);

内容的提问来源于stack exchange,提问作者Geng Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 17:27:24