如何生成标记二维NumPy数组各元素出现行索引的0-1矩阵
NumPy 实现方案
需求本质是构建取值-行号的存在性标记矩阵:矩阵行索引对应原数组的元素取值,列索引对应原数组的行号,取值在对应行出现则位置标1,否则标0。以下给出两种可直接运行的实现:
方法1:直观索引赋值(易读性优先)
逻辑非常直接:先初始化对应尺寸的全0矩阵,逐行扫描原数组,将当前行出现过的取值对应位置标记为1即可。
import numpy as np # 输入数组 input_array = np.array([[0, 4, 6], [5, 4, 1], [2, 1, 0], [4, 1, 0], [1, 5, 3]]) row_count = input_array.shape[0] max_value = input_array.max() # 初始化全0输出矩阵,尺寸为(取值总数 × 原数组行数) output_array = np.zeros((max_value + 1, row_count), dtype=int) for col_idx in range(row_count): # 提取当前行所有去重后的取值,避免重复赋值 current_values = np.unique(input_array[col_idx]) # 将对应取值行、当前列的位置设为1 output_array[current_values, col_idx] = 1
运行后得到的output_array和题目给出的期望结果完全一致。
方法2:纯矢量化运算(性能优先)
如果处理的数组规模很大,可以用NumPy广播机制实现无Python层循环的版本,运行效率更高:
# 生成所有待检测的取值,转为(取值总数, 1, 1)的形状用于广播 value_seq = np.arange(input_array.max() + 1).reshape(-1, 1, 1) # 广播对比后,判断每个取值是否在对应行存在,转为整数0/1 output_array = (value_seq == input_array).any(axis=2).astype(int)
逻辑说明:把0到最大值的取值序列调整为(取值数, 1, 1)的形状,和形状为(原数组行数, 原数组列数)的输入做相等判断时,会广播生成(取值数, 原数组行数, 原数组列数)的布尔数组,沿最后一个维度做any判断,只要对应位置有一个True就说明该取值在对应行存在,最后转成整型就是需要的0-1矩阵。
内容的提问来源于stack exchange,提问作者Nemanja Stojanovic
相关产品推荐
相关产品推荐

