求n维数组中从Bin索引获取包围网格点索引的通用解法
解决n维Bin到网格点索引的映射问题
这个问题的核心其实是n维空间中"单元格"到其顶点网格点的映射——因为Bin数组B的每个维度长度比G多1,每个Bin本质上对应G中相邻网格点围成的一个n维"超单元格",我们要找的就是这个单元格的所有顶点网格点索引。
下面是一个通用的n维解决方案,完全适配numpy的数组索引逻辑:
实现思路
- 把Bin的ravel索引转成n维坐标:用
np.unravel_index将一维索引转换为对应B数组的n维坐标,和numpy默认的行优先(C顺序)保持一致。 - 生成每个维度的有效网格点索引:对于Bin坐标的每个维度值
b_k,对应的网格点索引可能是b_k-1(如果b_k>0,避免越界)和b_k(如果b_k < G的该维度长度,避免越界)。 - 生成笛卡尔积得到所有网格点坐标:将各维度的有效索引做笛卡尔积,得到所有顶点的n维坐标。
- 转成G的ravel索引:用
np.ravel_multi_index把n维坐标转回一维索引,和G的ravel顺序一致。
代码实现
import numpy as np def bin_to_grid_indices(bin_idx, G_shape, B_shape): # 校验B和G的维度关系:B每个维度长度必须是G的+1 assert all(bs == gs + 1 for bs, gs in zip(B_shape, G_shape)), \ "B数组的每个维度长度必须比G数组对应维度大1" # 将Bin的一维索引转换为n维坐标 bin_coords = np.unravel_index(bin_idx, B_shape) # 为每个维度生成有效的网格点索引列表 valid_dim_indices = [] for b_k, g_dim_len in zip(bin_coords, G_shape): dim_options = [] if b_k > 0: dim_options.append(b_k - 1) if b_k < g_dim_len: dim_options.append(b_k) valid_dim_indices.append(dim_options) # 生成所有维度的笛卡尔积,得到网格点的n维坐标 # 使用indexing='ij'保证和numpy的数组索引逻辑一致 grid_coords = np.array(np.meshgrid(*valid_dim_indices, indexing='ij')).reshape(len(G_shape), -1).T # 将n维坐标转换为G数组的一维ravel索引 grid_indices = np.ravel_multi_index(grid_coords.T, G_shape) return grid_indices
测试你的示例
用你给出的测试数据验证:
G = np.arange(3*4).reshape(3, 4) B = np.arange(4*5).reshape(4, 5) bin_idx = 7 result = bin_to_grid_indices(bin_idx, G.shape, B.shape) print(result) # 输出: [1 2 5 6]
完全符合你预期的结果!
边界情况示例
比如测试Bin数组的角落索引:
- 当
bin_idx=0(B的(0,0)坐标),得到的网格点索引是[0](只有G的(0,0)点) - 当
bin_idx=4*5-1=19(B的最后一个索引,坐标(3,4)),得到的网格点索引是[11](G的(2,3)点) - 当
bin_idx=4(B的(0,4)坐标),得到的网格点索引是[3](G的(0,3)点)
这个方案可以无缝扩展到3维、4维甚至更高维度的数组,完全不需要修改核心逻辑。
内容的提问来源于stack exchange,提问作者Steve Heim
相关产品推荐
相关产品推荐

