Python 使用索引和子索引为numpy数组赋值
这已经咬了我好几次了,我不知道这是一个bug还是一个特性Python 使用索引和子索引为numpy数组赋值,python,numpy,numpy-slicing,Python,Numpy,Numpy Slicing,这已经咬了我好几次了,我不知道这是一个bug还是一个特性 nums = np.arange(10) indx1 = np.array([2,4,6,8]) indx2 = np.array([0,3]) 看起来我可以用任何一种方法索引nums nums[indx1][indx2], nums[indx1[indx2]] 输出(数组([2,8]),数组([2,8]) 如果我想重新分配这些值,这是行不通的 nums[indx1][indx2] = 20 nums 输出数组([0,1,2,3,4
nums = np.arange(10)
indx1 = np.array([2,4,6,8])
indx2 = np.array([0,3])
看起来我可以用任何一种方法索引nums
nums[indx1][indx2], nums[indx1[indx2]]
输出(数组([2,8]),数组([2,8])
如果我想重新分配这些值,这是行不通的
nums[indx1][indx2] = 20
nums
输出数组([0,1,2,3,4,5,6,7,8,9])
但这是意料之中的:
nums[indx1[indx2]] = 20
nums
输出数组([0,1,20,3,4,5,6,7,20,9])
为什么我必须嵌套索引数组而不是菊花链呢?以下是我的想法
尽管上述两种方法返回相同的结果,但在执行赋值操作时,它们是不同的
nums[indx1][indx2]
可分为两部分temp=nums[indx]
和temp[indx2]
第一步temp=nums[indx1]
切片将创建一个新的数组返回[2 4 6 8]
第二步<代码>临时[indx2]将返回[2,8]
因此,如果您尝试nums[indx1][indx2]=20
,它相当于
temp = nums[indx1]
print(temp)
temp[indx2] = 20
print(temp)
这不会影响原始数组nums
数组([0,1,2,3,4,5,6,7,8,9])
为什么第二种方法有效
indx1[indx2]
return[2,8]
nums[[2,8]]=20
将为您提供数组([0,1,20,3,4,5,6,7,20,9])
。它之所以有效,是因为您将值赋给原始数组nums
总的来说,第一个不能访问nums的内存,但是第二个可以。这似乎是一个合理的解释。但是,如果您试图为临时变量赋值,它不应该抛出异常吗?我想不出哪种情况下,你会想要一行代码什么都不做。@I.P.Freeley这并不是那么简单。例如,如果
indx1
是一个片或一个整数,则它不会执行任何操作,而是按预期工作。解析器无法轻松检测到这一点,因为Python是如此动态,以至于从代码中它通常无法知道nums
或indx1/2
的类型。在运行时很难检测到这两种情况,因为临时对象不知道它是临时的。啊,这解释了为什么我认为我过去能够做到这一点——我必须链接切片和索引,而不是两组索引。numpy
不会改变Python语法或计算顺序alist[1][2]
和arr[idx1][idx2]
的计算方法相同。不同之处在于列表类和数组类的\uuuuu getitem\uuuuuuuuuuuuuuuuuuuuu
(或\uuuuuuu setitem\uuuuuuuuuuuuuuu
)方法。