fgr*_*egg 4 python arrays numpy
我有一个2维numpy数组:
A = np.zeros(16).reshape(4,4)
Run Code Online (Sandbox Code Playgroud)
我希望(1, 1), (1,3), (3,1),并且(3,3)单元格的值为1.
A[[1,3], [1:3]] = 1
Run Code Online (Sandbox Code Playgroud)
只分配1 (1,1)和(3,3).
A[[1,3], :][:, [1, 3]] = 1
Run Code Online (Sandbox Code Playgroud)
不起作用,因为它使数据的副本不是视图.这样做的正确方法是什么?
使用步骤= 2的切片:
A[1::2,1::2] = 1
Run Code Online (Sandbox Code Playgroud)
或者明确地传递所有索引:
A[[1,1,3,3],[1,3,1,3]] = 1
Run Code Online (Sandbox Code Playgroud)
通常,当您使用数组以这种方式索引另一个数组时,numpy期望每个数组R,C等具有相同的形状。例如,假设您想从此数组中提取非零值:
>>> a
array([[1, 3, 0, 0],
[0, 0, 0, 0],
[2, 4, 0, 0],
[0, 0, 0, 0]])
Run Code Online (Sandbox Code Playgroud)
您将创建一个行索引数组R:
>>> R
array([[0, 2],
[0, 2]])
Run Code Online (Sandbox Code Playgroud)
和一个列索引数组C:
>>> C
array([[0, 0],
[1, 1]])
Run Code Online (Sandbox Code Playgroud)
并像这样传递它们:
>>> a[R, C]
array([[1, 2],
[3, 4]])
Run Code Online (Sandbox Code Playgroud)
请注意,它们可以是您喜欢的任何形状——输出将采用相同的形状:
>>> RR
array([0, 2, 0, 2])
>>> CC
array([0, 0, 1, 1])
>>> a[RR, CC]
array([1, 2, 3, 4])
Run Code Online (Sandbox Code Playgroud)
但是,如果您的索引数组中有重复项,那么您可以通过使用广播来省去一些麻烦。唯一的问题是结果数组必须能够广播。这意味着您需要明确地赋予它们额外的维度。我将使用切片语法来保留额外的维度。
>>> r = R[0:1,:]
>>> c = C[:,0:1]
>>> r
array([[0, 2]])
>>> c
array([[0],
[1]])
>>> a[r, c]
array([[1, 2],
[3, 4]])
Run Code Online (Sandbox Code Playgroud)
如果你没有明确地给他们额外的维度,numpy尽最大努力理解你所传递的内容,但它并不总是按预期工作。将0:1切片替换为0删除额外的维度:
>>> rr = r[0,:]
>>> cc = c[:,0]
>>> rr
array([0, 2])
>>> cc
array([0, 1])
>>> a[rr, c]
array([[1, 2],
[3, 4]])
>>> a[r, cc]
array([[1, 4]])
>>> a[rr, cc]
array([1, 4])
Run Code Online (Sandbox Code Playgroud)
第一个 ( a[rr, c]) 之所以有效,是因为numpy可以从它的形状看出c它应该广播。但另外两个是不明确的,因此numpy假设您并不打算广播它们。
但是,请注意,这numpy也提供了使平面数组可广播的快捷方式。这可以派上用场!
>>> a[numpy.ix_(rr, cc)]
array([[1, 3],
[2, 4]])
Run Code Online (Sandbox Code Playgroud)