在ndarray中引用ndarray行

时间:2017-12-22 18:51:06

标签: python numpy

是否可以在另一个numpy数组中存储numpy数组的特定行的引用?

我有一个2D节点数组,例如

nodes = np.array([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]])

现在我想只选择其中一些并将引用存储在另一个numpy数组中:

nn = np.array([nodes[0], nodes[3]])

如果我修改nn中的条目,则数组nodes保持不变。有没有办法在ndarray nodes中存储对nn的引用?

4 个答案:

答案 0 :(得分:2)

如果可以使用basic indexing/slicing创建引用,那么您将获得一个view(一个不拥有其数据的数组,而是引用另一个数组的数据)的初始数组,其中更改传播:

>>> nn = nodes[0:4:3] # reference array for rows 0 and 3
>>> nn[0][0] = 0
>>> nodes
array([[0, 2],
       [2, 3],
       [3, 4],
       [4, 5],
       [5, 6]])

否则,您将从代码中获取原始数组的副本,并且更新不会传播到初始数组。

答案 1 :(得分:1)

您可以将索引存储到numpy数组中所需的行:

ref = np.array([0, 3])

您可以使用索引表达式中的引用来访问所需的节点:

>>> nn = nodes[ref]
>>> nn
array([[1, 2],
       [4, 5]])

nn将是一个深层副本,在这种情况下与原始版本无关。虽然nn[foo] = bar不会影响原始数组,但您可以直接使用ref

>>> nodes[ref, 1] = [17, 18]
>>> nodes
array([[ 1, 17],
       [ 2,  3],
       [ 3,  4],
       [ 4, 18],
       [ 5,  6]])

或者,您可以使用ref的掩码:

>>> ref2 = np.zeros(nodes.shape[0], dtype=np.bool)
>>> ref2[ref] = True
>>> ref2
array([ True, False, False,  True, False], dtype=bool)

您几乎可以完成所有相同的操作:

>>> nn2 = nodes[ref2]
>>> nn2
array([[1, 2],
       [4, 5]])

修改也有效:

>>> nodes[ref2, 1] = [19, 23]
>>> nodes
array([[ 1, 19],
       [ 2,  3],
       [ 3,  4],
       [ 4, 23],
       [ 5,  6]])

索引数组唯一更方便的是从选择中选择一个特定节点:

 >>> nodes[ref[0], 0]
 1

答案 2 :(得分:0)

方法1

首先,使用dtype = object初始化Numpy数组None。 (它不一定是None。我猜你只是不能在初始化时放置引用,因为Numpy不知何故只是创建了它的深层副本。)

然后,将引用放入数组中。

nodes = np.array([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]])
# nn = np.array([nodes[0], nodes[1]],dtype=object) would not work
nn = np.array([None, None], dtype=object)
nn[0] = nodes[0]
nn[1] = nodes[3]
# Now do some modification.
nn[0][1] = 100

Output of nodes:
array([[  1, 100],
       [  2,   3],
       [  3,   4],
       [  4,   5],
       [  5,   6]])

# make it a function
def make_ref(old_array, indeces):
    ret = np.array([None for _ in range(len(indeces))])
    for i in range(len(indeces)):
        ret[i] = old_array[indeces[i]]
    return ret

nn = make_ref(nodes, [0, 3])

方法2
如果您不需要将它放在Numpy数组中,只需使用列表来托管引用。

nn = [nodes[0], nodes[1]]

答案 3 :(得分:0)

在Numpy中,您可以获得可以编辑的数组视图。在您的示例中,您可以执行此操作:

import numpy as np
nodes = np.array([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]])
node_idx = np.array([0, 3])
nodes[node_idx] = np.array([[1, 5], [2, 5]])
nodes

输出:

array([[1, 5],
       [2, 3],
       [3, 4],
       [2, 5],
       [5, 6]])

您也可以用布尔数组替换它:

import numpy as np
nodes = np.array([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]])
node_mask = np.array([True, False, False, True, False])
nodes[node_mask] = np.array([[1, 5], [2, 5]])
nodes

产生相同的结果。当然,这意味着你可以做到这样的魔术:

import numpy as np
nodes = np.array([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]])
nodes[nodes[:, 0] == 3] = [1, 5]
nodes

使用3替换第一个元素等于[1, 5]的所有行。输出:

array([[1, 2],
       [2, 3],
       [1, 5],
       [4, 5],
       [5, 6]])