numpy数组fancy indexing取值形状不匹配及code2正常运行原因求解
问题原因与解答
1. code1报错的核心原因
numpy在处理**单个方括号内的混合索引(同时包含标量整数、切片、列表/数组类型的高级索引)**时,会自动将高级索引对应的维度移动到所有维度的最前方。
你的data数组原始shape为(2, 3, 50, 25, 1),执行data[n, :, valid_frame_id_ls, :, :]时:
- 第一个位置
n是标量整数索引,会直接消去第一维 - 第二个位置
:是切片,对应长度为3的通道(C)维度 - 第三个位置
valid_frame_id_ls是长度为5的列表,属于高级索引
按照上述规则,高级索引对应的长度为5的维度会被提到最前面,最终返回数组的shape为(5, 3, 25, 1),和左侧赋值目标new_data[n, :, :len(valid_frame_id_ls), :, :]的shape(3, 5, 25, 1)前两维顺序完全相反,无法进行广播赋值,因此抛出ValueError。
2. code2正常运行的原因
code2使用的是分步索引(连续多个方括号索引),不会触发混合索引的维度移动规则:
- 第一步执行
data[n]先取出单个样本,得到shape为(3, 50, 25, 1)的4维数组 - 第二步对该4维数组执行
[:, valid_frame_id_ls, :, :]索引,此时索引中只有切片和高级索引,没有标量整数索引和高级索引混合,高级索引对应的维度会保留在原来的T轴位置,返回数组的shape为预期的(3, 5, 25, 1),和左侧赋值目标的shape完全匹配,因此可以正常运行。
3. 其他可行的修复方案
如果不想用分步索引,也可以手动调整返回数组的维度顺序:
# 调整code1返回数组的前两维顺序 new_data[n, :, :len(valid_frame_id_ls), :, :] = data[n, :, valid_frame_id_ls, :, :].transpose(1, 0, 2, 3)
也可以用np.take显式指定索引的轴,避免维度顺序问题:
new_data[n, :, :len(valid_frame_id_ls), :, :] = np.take(data[n], valid_frame_id_ls, axis=1)
内容的提问来源于stack exchange,提问作者GuangJun Liu
相关产品推荐
相关产品推荐

