简体   繁体   English

引用ndarray中的ndarray行

[英]Reference to ndarray rows in ndarray

is it possible to store references of specific rows of an numpy array in another numpy array? 是否可以在另一个numpy数组中存储numpy数组的特定行的引用?

I have an array of 2D nodes, eg 我有一个二维节点数组,例如

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

Now I want to select only a few of them and store a reference in another numpy array: 现在,我只想选择其中一些并将引用存储在另一个numpy数组中:

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

If I modify a entry in nn the array nodes remains unchanged. 如果我在nn修改条目,则数组nodes保持不变。 Is there a way to store a reference to nodes in the ndarray nn ? 有没有一种方法可以存储对ndarray nn nodes的引用?

If the reference can be created with basic indexing/slicing , then you get a view (an array that does not own its data, but refers to another array's data instead) of the initial array where changes propagate: 如果可以使用基本索引/切片创建引用,那么您将获得传播变化的初始数组的视图 (一个不拥有其数据,但引用另一个数组的数据的数组):

>>> 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]])

Otherwise, you get a copy from the original array as in your code, and updates do not propagate to the initial array. 否则,您将像在代码中那样从原始数组中获取一个副本,并且更新不会传播到初始数组。

You can store an index to the rows you want in a numpy array: 您可以将索引存储到numpy数组中所需的行:

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

You can use the reference in an indexing expression to access the nodes you want: 您可以在索引表达式中使用引用来访问所需的节点:

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

nn will be a deep copy with no connection to the original in this case. 在这种情况下, nn将是一个深副本,与原始副本没有任何关系。 While nn[foo] = bar won't affect the original array, you can use ref directly: 尽管nn[foo] = bar不会影响原始数组,但是您可以直接使用ref

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

Alternatively, you can use a mask for ref : 另外,您也可以将遮罩用于ref

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

You can do almost all the same operations: 您几乎可以执行所有相同的操作:

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

Modifications work too: 修改也可以:

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

The only thing that is more convenient with an array of indices is selecting a particular node from within the selection: 使用索引数组唯一更方便的是从选择中选择特定节点:

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

Method 1 方法1

First, initialize a Numpy array of None with dtype=object. 首先,使用dtype = object初始化一个None的Numpy数组。 (It don't have to be None. My guess it that you just cannot put references at initialization as Numpy somehow just creates an deep copy of it.) (它不一定非要是None。我猜想您只是不能在初始化时放置引用,因为Numpy会以某种方式创建它的深层副本。)

Then, put the reference into the array. 然后,将引用放入数组中。

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])

Method 2 方法二
If you don't need to put it in Numpy arrays, just use a list to host the references. 如果不需要将其放在Numpy数组中,只需使用列表来托管引用。

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

In Numpy, you can get a view of an array that can be edited. 在Numpy中,您可以查看可以编辑的数组的视图。 In your example, you can do this: 在您的示例中,您可以执行以下操作:

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

Output: 输出:

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

You can also replace it with boolean arrays: 您也可以将其替换为布尔数组:

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

Which produces the same result. 产生相同的结果。 Of course, this means you can do magic like this: 当然,这意味着您可以像这样做魔术:

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

Which replaces all rows with the first element equal to 3 with [1, 5] . [1, 5]替换第一个等于3的第一个元素的所有行。 Output: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM