如何用Pythonic方式通过n×2的numpy索引切片numpy数组?
无需循环的Numpy切片实现方式
你可以通过直接生成所有需要的列索引,然后一次性索引data来实现,完全避免循环和中间列表。下面是两种简洁的实现方式:
方法一:列表推导生成索引(简洁直观)
这种写法简洁易懂,属于Pythonic风格:
import numpy as np idx = np.array([[1,3],[5,7], [9,11]], dtype=np.int64) data = np.arange(30).reshape(2, 15) # 生成所有需要提取的列索引 indices = np.concatenate([np.arange(s, e) for s, e in idx]) # 直接索引得到结果 result = data[:, indices]
方法二:纯Numpy数组操作(无显式循环)
如果想要完全规避任何形式的循环(包括列表推导),可以通过Numpy的广播和数组操作生成索引:
import numpy as np idx = np.array([[1,3],[5,7], [9,11]], dtype=np.int64) data = np.arange(30).reshape(2, 15) # 计算每个切片的长度 slice_lengths = idx[:, 1] - idx[:, 0] # 生成每个切片内的相对位置索引 relative_indices = np.repeat(np.arange(slice_lengths.max()), slice_lengths.size) # 过滤超出当前切片长度的索引 relative_indices = relative_indices[relative_indices < np.repeat(slice_lengths, slice_lengths.max())] # 计算最终绝对索引 absolute_indices = np.repeat(idx[:, 0], slice_lengths) + relative_indices # 索引得到结果 result = data[:, absolute_indices]
两种方法的输出结果和原代码完全一致:
array([[ 1, 2, 5, 6, 9, 10], [16, 17, 20, 21, 24, 25]])
说明
- 方法一兼顾简洁性与可读性,是日常开发更推荐的写法。
- 方法二完全依赖Numpy数组操作,适合追求极致性能或必须避免循环的场景,但代码复杂度稍高。
内容的提问来源于stack exchange,提问作者Chuang Men
相关产品推荐
相关产品推荐

