Python NumPy-分配给函数返回的视图
假设我有一个N-D数组Python NumPy-分配给函数返回的视图,python,arrays,numpy,Python,Arrays,Numpy,假设我有一个N-D数组a和一个函数f(a),它返回a的任何复杂视图v,还有一个数组b,其形状与v相同 将b分配给v的最简单方法是什么?它们都可以是多维的 最简单的尝试,如分配给函数返回值的下一个代码,失败并出现错误:SyntaxError:cannotassign to function call: import numpy as np a, b = np.arange(10), np.arange(2) a[2:4] = b # Working f = lambda a: a[2:4] # R
a
和一个函数f(a)
,它返回a
的任何复杂视图v
,还有一个数组b
,其形状与v
相同
将b
分配给v
的最简单方法是什么?它们都可以是多维的
最简单的尝试,如分配给函数返回值的下一个代码,失败并出现错误:SyntaxError:cannotassign to function call
:
import numpy as np
a, b = np.arange(10), np.arange(2)
a[2:4] = b # Working
f = lambda a: a[2:4] # Returns any view of a
f(a) = b # Not working, syntax error
通过该任务,不允许将数组
b
参数传递给函数f
,函数本身应该是未修改的。我刚刚想出了一个最简单的解决方案,它适用于除0维数组(标量)外的任何N-D情况:
@hpaulj适用于任何维度的下一个解决方案(与解决方案不同):
在试图找到解决方案之前,请确保您了解问题所在
In [27]: a, b = np.arange(10), np.arange(2)
In [28]: f = lambda a: a[2:4]
In [29]: f(a)
Out[29]: array([2, 3])
In [30]: f(a) = b
File "<ipython-input-30-df88b52b4d3c>", line 1
f(a) = b
^
SyntaxError: can't assign to function call
所需的分配切片是:
In [33]: a[2:4] = b
In [34]: a.__setitem__(slice(2,4),b)
In [35]: a
Out[35]: array([0, 1, 0, 1, 4, 5, 6, 7, 8, 9])
请注意,setitem
将b
作为参数a.uuu setitem_uuuuu(slice(2,4))=b
将遇到相同的语法错误
使用setitem
可以使用高级索引(列表):
如果这不起作用:
In [40]: a[[0,2]][...] = b
因为它实际上是
a.\uuuu getitem\uuuuuuuu([0,2])。\uuuuu setitem\uuuuuuuuuu(省略号,b)
。集合修改get生成的副本。此链接仅在第一个索引生成视图
x[…]=…
触发setitem
方法调用时有效-@谢谢!实际上,我指的是我在回答中讨论的那种行动。我的意思是x[一些索引]=一些值
,而不是字面上使用省略号
。在您的答案中,使用省略号而不是切片(无)
更一般。这是唯一正确的答案。你应该考虑删除另一个。@疯子,另一个有什么不对吗?在大多数情况下,只要是一种不同的解决或几乎解决任务的方法,任何答案都可以被允许。至少我以后肯定会接受这个。StackOverflow上有数千个问题,列出了同一任务的几十种不同解决方案,只是因为有更好的解决方案,这些答案的多寡不会被删除。至少我认为另一个答案中的解决方案可能大部分时间都被NumPy的新手使用。它不适用于0D阵列。自从你注意到后,我取消了反对票that@MadPhysicist你是对的,这个解决方案并没有覆盖100%的用例,但仍然有很多StackOverflow答案并没有覆盖所有的角落案例,他们通常会像我在另一个解决方案中一样提到这些未覆盖的案例。我的两个答案有问题吗?它们都产生正确的结果,底层数组a
被正确修改。或者你只是想详细解释下面发生了什么?在我的问题中,我特别强调我的函数总是返回一个可写的视图。也许在numpy中有一些函数以某种方式断言,从函数返回的东西实际上是数组的视图,而不是副本?
In [31]: a[2:4]
Out[31]: array([2, 3])
In [32]: a.__getitem__(slice(2,4))
Out[32]: array([2, 3])
In [33]: a[2:4] = b
In [34]: a.__setitem__(slice(2,4),b)
In [35]: a
Out[35]: array([0, 1, 0, 1, 4, 5, 6, 7, 8, 9])
In [38]: a[[0,2]] = b
In [39]: a.__setitem__([0,2],b)
In [40]: a[[0,2]][...] = b