如何无循环用numpy按每行不同列索引切片二维数组并修改原数组?
按行取不同列索引并修改原numpy数组的方法
针对你提出的需求——既要按行选取不同的列索引切片,又要能直接修改原数组,我来给你分场景说明解决方案:
一、仅读取数据:用np.take_along_axis快速实现
如果只是需要读取指定位置的数据,你提到的np.take_along_axis确实是简洁高效的选择:
import numpy as np x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) indices = np.array([[0, 1], [2, 1], [2, 2]]) result = np.take_along_axis(x, indices, axis=1) print(result) # 输出:[[0 1] # [5 4] # [8 8]]
但正如你所说,这个函数返回的是原数组的副本,所以无法通过它直接修改原数组(比如np.take_along_axis(...) +=10只会修改副本,原数组不会变化)。
二、修改原数组:构造行+列双索引直接操作
要直接修改原数组的指定元素,核心是给每个要操作的元素明确指定行和列的坐标。具体实现如下:
- 构造与
indices形状完全一致的行索引数组:每行的行号重复对应次数(比如每行取2列,行索引就重复2次)。 - 用行索引数组和
indices列索引数组一起对原数组做花式索引,直接修改元素。
实现代码:
import numpy as np x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) indices = np.array([[0, 1], [2, 1], [2, 2]]) # 构造行索引数组,形状和indices一致:[[0,0], [1,1], [2,2]] row_indices = np.indices(indices.shape)[0] # 直接修改原数组的指定位置 x[row_indices, indices] += 10 print(x) # 输出:[[10 11 2] # [ 3 14 15] # [ 6 7 18]]
原理说明:
np.indices(indices.shape)[0]会生成一个和indices形状相同的数组,其中每个位置的值是该位置所在的行号。配合indices的列索引,我们就精准定位到了所有要修改的元素的坐标,此时对x[row_indices, indices]的赋值操作会直接作用于原数组的内存空间,而非副本,完美满足你的修改需求。
如果你觉得np.indices不够直观,也可以用np.arange构造行索引,效果完全一致:
row_indices = np.arange(x.shape[0])[:, None].repeat(indices.shape[1], axis=1)
内容的提问来源于stack exchange,提问作者DiveIntoML
相关产品推荐
相关产品推荐

