高效识别二维数组中满足列元素双向匹配条件的实例
问题
现有一个3D numpy数组arr,需要在其每个二维子数组arr[0]、arr[1]、arr[2]中,识别满足以下条件的实例:同一列中,第q行存在元素p,且第p行存在元素q。
当前通过多层嵌套for循环与if语句实现识别,但处理大规模数组时效率低下,请求更高效的实现方案。理想输出为包含i(二维子数组索引)、row1、val1、row2、val2的numpy二维数组,示例输出如下:
output = [[0, 0, 3, 3, 0], [0, 1, 2, 2, 1], [0, 2, 3, 3, 2], [1, 0, 2, 2, 0], [1, 2, 3, 3, 2], [2, 1, 3, 3, 1], [2, 0, 3, 3, 0], [2, 1, 2, 2, 1]]
现有实现代码:
import numpy as np arr = np.array( [[[1, 3, 5, 0], [8, 2, 4, 7], [4, 1, 3, 1], [9, 0, 2, 6]], [[9, 2, 6, 1], [2, 4, 0, 7], [4, 0, 3, 5], [5, 1, 2, 0]], [[7, 3, 6, 1], [3, 2, 0, 4], [6, 1, 2, 3], [1, 0, 5, 9]]]) for i in range(3): curr_arr = arr[i] num_rows, num_cols = curr_arr.shape for col in range(num_cols): for row1 in range(num_rows): for row2 in range(num_rows): if row1 != row2 and row1 < row2: val1 = curr_arr[row1, col] val2 = curr_arr[row2, col] if val1==row2 and val2 == row1: print(i) print(row1, val1) print(row2, val2) print()
高效实现方案
利用numpy的向量化操作替代嵌套循环,大幅提升处理大规模数组的效率,步骤如下:
1. 生成全局索引矩阵
先创建对应3D数组的三维索引(子数组索引i、行索引row、列索引col),再通过广播生成所有row1和row2的组合:
import numpy as np # 原数组 arr = np.array( [[[1, 3, 5, 0], [8, 2, 4, 7], [4, 1, 3, 1], [9, 0, 2, 6]], [[9, 2, 6, 1], [2, 4, 0, 7], [4, 0, 3, 5], [5, 1, 2, 0]], [[7, 3, 6, 1], [3, 2, 0, 4], [6, 1, 2, 3], [1, 0, 5, 9]]]) # 获取数组维度 n_subarr, n_rows, n_cols = arr.shape # 生成所有索引组合:i, col, row1, row2 i = np.arange(n_subarr)[:, None, None, None] col = np.arange(n_cols)[None, :, None, None] row1 = np.arange(n_rows)[None, None, :, None] row2 = np.arange(n_rows)[None, None, None, :]
2. 筛选符合条件的组合
通过向量化条件判断,一次性筛选出满足要求的实例:
# 提取对应位置的值 val1 = arr[i, row1, col].squeeze() val2 = arr[i, row2, col].squeeze() # 条件:row1 < row2,且val1 == row2,val2 == row1 mask = (row1 < row2) & (val1 == row2) & (val2 == row1) # 提取符合条件的索引和值 valid_i = i[mask].flatten() valid_row1 = row1[mask].flatten() valid_val1 = val1[mask].flatten() valid_row2 = row2[mask].flatten() valid_val2 = val2[mask].flatten()
3. 整理成目标输出格式
将筛选结果拼接成二维数组:
# 组合成输出数组 output = np.column_stack([valid_i, valid_row1, valid_val1, valid_row2, valid_val2]) print(output)
运行上述代码后,输出结果与示例完全一致,且避免了多层循环,处理大规模数组时效率提升显著。
内容的提问来源于stack exchange,提问作者user109387
相关产品推荐
相关产品推荐

