如何用另一个二维数组对NumPy二维数组逐行切片
时间:2026-08-18 | 作者:冻月看渠 | 阅读:0这里介绍一种更高效、也更适合向量化处理的思路:结合布尔掩码和 np.take_along_axis,按照另一组二维数组中给出的每行起止索引,对目标二维数组逐行完成切片,并用 0 统一补齐,从而让最终结果保持一致的形状。
本文介绍一种高效、向量化的方法:利用布尔掩码与 np.take_along_axis,根据每行指定的起止索引(存储于另一二维数组中)对目标二维数组进行逐行切片,并统一填充零以保持形状一致。
在 NumPy 里,如果想对二维数组按行做变长切片,也就是让每一行都使用不同的 [start:end] 范围,单靠常规切片语法其实办不到。
根本原因在于,返回结果的形状并不规整。不过,这并不意味着只能回到 Python 循环。借助向量化的逻辑运算,再配合索引重排,这件事依然可以高效完成。
核心思路
整个方案可以分为四步。
- 生成列索引序列:用
np.arange(a.shape[1])创建[0, 1, 2, ..., n-1]。 - 构建布尔掩码:通过广播比较列索引是否落在每行对应的
[start, end]区间内(含端点)。 - 掩码赋值:用
np.where(m, a, 0)将非目标区域置零,得到初步掩码数组。 - 右对齐重排:对每行的布尔掩码取反后排序,获得“True 在前、False 在后”的索引顺序,再用
np.take_along_axis重排整行数据,实现右侧填充零的效果。
完整代码示例
以下是完整可运行代码:
import numpy as np np.random.seed(0) a = np.random.randint(0, 999, (4, 5)) # array([[684, 559, 629, 192, 835], #[763, 707, 359, 9, 723], #[277, 754, 804, 599,70], #[472, 600, 396, 314, 705]]) idx = np.array([[2, 4],# row 0: slice [2:5] → indices 2,3,4 [0, 3],# row 1: slice [0:4] → indices 0,1,2,3 [2, 3],# row 2: slice [2:4] → indices 2,3 [1, 3]]) # row 3: slice [1:4] → indices 1,2,3 # Step 1: column indices cols = np.arange(a.shape[1]) # Step 2: broadcasted boolean mask (shape: (4, 5)) m = (cols >= idx[:, 0, np.newaxis]) & (cols <= idx[:, 1, np.newaxis]) # Step 3: zero-out non-selected elements a_mask = np.where(m, a, 0) # Step 4: sort indices to move True-masked values to left (right-aligned zeros) sort_idx = np.argsort(~m, axis=1)# ~m: False→True, True→False; argsort puts True first result = np.take_along_axis(a_mask, sort_idx, axis=1) print(result)
输出结果
[[629 192 835 0 0] [763 707 359 9 0] [804 599 0 0 0] [600 396 314 0 0]]
关键说明
idx[:, 0, np.newaxis]利用np.newaxis扩展维度,使(4,)变为(4, 1),从而与(5,)的cols广播成(4, 5)。~m将掩码反转,选中区域变为False。argsort默认升序排列,因此False会排在前面。这正是我们右对齐所需的行为。- 此方法完全向量化,适用于大规模数组,性能远优于
for循环或np.vectorize。
注意事项
idx中的索引必须合法(0 ≤ start ≤ end < a.shape[1]),否则掩码可能出错。建议提前校验,或用np.clip安全截断。- 若需左对齐,即保留原始列顺序,仅补零在右侧,可跳过第 4 步,直接使用
a_mask。它已天然满足左对齐语义。 - 本方案默认包含
end索引,也就是闭区间。若需 NumPy 原生切片语义[start:end),请将<=改为<。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- 微服务跨库调用场景解析:一个服务调用另一个服务
- 时间:2026-08-21
-
- 剪映手机版如何提取视频声音并添加到另一个视频中
- 时间:2026-08-13
-
- 手机QQ怎么给另一个QQ号传送文件最快
- 时间:2026-08-12
-
- Apple Music提示此设备已关联另一个 Apple ID 具体是什么原因
- 时间:2026-07-25
-
- Excel移动与复制工作表的区别及跨工作簿移动图文步骤
- 时间:2026-07-25
-
- PS如何快速应用另一个PSD文件效果的操作步骤
- 时间:2026-07-24
-
- PS中如何将图层复制到另一个文件的详细步骤
- 时间:2026-07-23
-
- PS中如何复制图层到另一个画布的步骤详解
- 时间:2026-07-23
精选合集
更多大家都在玩
大家都在看
更多-
- 糖尿病完全不能吃糖吗
- 时间:2026-09-15
-
- 蚂蚁庄园小课堂2026年9月16日最新题目答案
- 时间:2026-09-15
-
- 小鸡答题今天的答案是什么2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园每日答题答案2026年9月16日
- 时间:2026-09-15
-
- 以下哪种粮食是酿造绍兴黄酒的主要原料 蚂蚁庄园今日答案9月16日
- 时间:2026-09-15
-
- 劝学名句“及时当勉励,岁月不待人”出自哪位诗人 蚂蚁庄园今日答案9.16
- 时间:2026-09-15
-
- 蚂蚁庄园今天答题答案2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园答题今日答案2026年9月16日
- 时间:2026-09-15
