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

为何Numpy切片与花式索引返回不同形状?含具体案例疑问

Numpy切片与花式索引的形状差异解析

对以下两种Numpy索引场景的返回形状存在疑惑,尤其不解x[:, [1], :, [1]]的形状为何是(1, 2, 2)——维度0用切片:本应保留原维度值2,想明确该形状的确定逻辑。

测试代码

import numpy as np

x = np.arange(2 * 2 * 2 * 2).reshape((2, 2, 2, 2))
print(f"x:\n{x}")
a = x[:, [1], [1], :]
print("==================")
print(f"shape of x[:, [1], [1], :] == {a.shape}")
print(a)
print("==================")
b = x[:, [1], :, [1]]
print(f"shape of x[:, [1], :, [1]] == {b.shape}")
print(b)

运行结果

x:
[[[[ 0  1]
   [ 2  3]]

  [[ 4  5]
   [ 6  7]]]


 [[[ 8  9]
   [10 11]]

  [[12 13]
   [14 15]]]]
==================
shape of x[:, [1], [1], :] == (2, 1, 2)
[[[ 6  7]]

 [[14 15]]]
==================
shape of x[:, [1], :, [1]] == (1, 2, 2)
[[[ 5  7]
  [13 15]]]

核心规则:花式索引的广播机制

Numpy中,切片:仅保留原维度结构,但花式索引(用列表/数组索引)会触发广播机制——当多个维度同时使用花式索引时,所有索引数组会被广播到共同的形状,最终结果的形状就是这个广播后的形状。切片:会被自动转换为对应维度的全索引数组,参与广播计算。


案例1:x[:, [1], [1], :]的形状解析

各维度的索引类型与对应数组:

  • 维度0:: → 等价于索引数组[0,1],形状(2,)
  • 维度1:[1] → 索引数组,形状(1,)
  • 维度2:[1] → 索引数组,形状(1,)
  • 维度3:: → 等价于索引数组[0,1],形状(2,)

广播过程:
所有索引数组会被扩展到共同的形状(2,1,2):

  • 维度0的(2,)扩展为(2,1,2)
  • 维度1、2的(1,)广播为(2,1,2)
  • 维度3的(2,)扩展为(2,1,2)

最终结果形状为(2,1,2),对应每个维度0的元素,取维度1=1、维度2=1的位置,再保留维度3的所有元素。


案例2:x[:, [1], :, [1]]的形状解析

各维度的索引类型与对应数组:

  • 维度0:: → 等价于索引数组[0,1],形状(2,)
  • 维度1:[1] → 索引数组,形状(1,)
  • 维度2:: → 等价于索引数组[0,1],形状(2,)
  • 维度3:[1] → 索引数组,形状(1,)

广播过程:
所有索引数组会被扩展到共同的形状(1,2,2):

  • 维度1的(1,)作为第一个维度,扩展为(1,1,1)后广播到(1,2,2)
  • 维度0的(2,)作为第二个维度,扩展为(1,2,1)后广播到(1,2,2)
  • 维度2的(2,)作为第三个维度,扩展为(1,1,2)后广播到(1,2,2)
  • 维度3的(1,)广播后不新增维度

最终结果形状为(1,2,2),对应取维度1=1、维度3=1的所有组合:每个维度0的元素搭配每个维度2的元素,形成(2,2)的子数组,再被维度1的单元素索引包裹为(1,2,2)的整体形状。


关键总结

  • 切片仅保留原维度,不触发广播;花式索引会将索引数组广播到共同形状,结果形状由广播后的形状决定。
  • 当花式索引分布在非连续维度时,广播后的形状会重新排列维度顺序,这就是x[:, [1], :, [1]]中维度0的2没有出现在第一个位置的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 07:15:51