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

如何将ndarray大部分元素置零,仅保留指定索引位置的数值

高效实现方案

针对你的需求,不需要逐行循环,使用Numpy原生高级索引即可实现,且完全适配「保留元素远少于无关元素」的场景,性能远高于逐行操作。

最高效方案:全零数组批量赋值

直接通过Numpy构造行、列索引数组,批量赋值需要保留的元素,时间复杂度仅和你需要保留的元素数量挂钩:

import numpy as np

# 构造行索引:每个行号重复i_array每行的元素个数次
rows = np.repeat(np.arange(z_array.shape[0]), i_array.shape[1])
# 构造列索引:直接将i_array展平即可
cols = i_array.ravel()

# 生成同维度全零数组
a_array = np.zeros_like(z_array)
# 批量赋值需要保留的元素
a_array[rows, cols] = z_array[rows, cols]

用你给出的示例代码测试,输出结果和预期的a_array完全一致。

关于numpy.ufunc.at的说明

np.ufunc.at确实可以实现该需求,但它的适用场景是索引存在重复、需要原地累加或重复赋值的情况。如果你的i_array每行不存在重复索引,普通高级索引赋值的性能比ufunc.at更高,无需额外使用。如果存在重复索引需要保留赋值结果,可以使用如下写法:

a_array = np.zeros_like(z_array)
# 两种写法均可,根据实际场景选择
np.put(a_array, np.ravel_multi_index((rows, cols), z_array.shape), z_array[rows, cols])
# 或ufunc.at写法
np.add.at(a_array, (rows, cols), z_array[rows, cols])

第三种实现思路:布尔掩码过滤

你可以生成布尔掩码数组,直接过滤原数组的元素,适合需要保留原z_array不被修改的场景:

mask = np.zeros(z_array.shape, dtype=bool)
mask[rows, cols] = True
a_array = z_array * mask

该方案的可读性很高,性能和第一种方案接近,缺点是会多一次数组乘法运算,超大规模数组下性能略低于第一种方案。

性能对比说明

你提到的第二种思路「直接在z_array基础上将无关位置置零」不推荐使用,因为无关元素数量远大于需要保留的元素,置零操作需要处理的元素量是第一种方案的几十倍,性能差距非常明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:06:06