简体   繁体   English

在numpy数组副本中交换元素

[英]Swapping elements in a copy of a numpy array

I have a list/array of numpy arrays, representing objects split into subgroups. 我有一个numpy数组的列表/数组,表示将对象分成子组。

I would like to create a copy of this array where I can swap elements within the subgroups and leave the original groupings unchanged. 我想创建此数组的副本,在其中可以交换子组中的元素并使原始分组保持不变。

The function I've written to do this is: 我为此编写的函数是:

def group_swap(groups):
# Chooses two random groups and swaps two random elements from each 
group.
    gr = np.copy(groups)
    g1 = np.random.randint(len(gr))
    g2 = np.random.randint(len(gr))
    if g1 != g2:
        e1 = np.random.randint(len(gr[g1]))
        e2 = np.random.randint(len(gr[g2]))
        gr[g1][e1] ,gr[g2][e2] = gr[g2][e2].copy(),gr[g1][e1].copy()
        return(gr)
    else:
        return(groups)

Based on this question , I've been able to swap the elements. 基于这个问题 ,我已经能够交换元素。 However, the elements in the original array are also swapped, as in this example. 但是,如本例所示,原始数组中的元素也被交换。

a = np.array_split(np.arange(10),3)
print('orginal before swap: ',a)
a_swap = group_swap(a)
print('original after swap: ',a)
print('swapped array: ',a_swap)

Which gives: 这使:

original before swap:  
[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8, 9])]
original after swap:  
[array([0, 1, 2, 7]), array([4, 5, 6]), array([3, 8, 9])]
swapped array:  
[array([0, 1, 2, 7]) array([4, 5, 6]) array([3, 8, 9])]

Ideally, the array a should be unchanged and only a_swap show the swapped elements. 理想情况下,数组a应该保持不变,只有a_swap显示交换的元素。 I had hoped that making and working with a copy of the array within my function would do the trick but that hasn't worked. 我曾希望在函数中创建并使用数组的副本能够达到目的,但那没有用。

Could anyone help point out what I might be missing? 任何人都可以帮助指出我可能会缺少的东西吗? I have a feeling it's something I'll kick myself for afterwards. 我感觉这是我以后会踢自己的东西。

Thanks 谢谢

PS: Oddly enough, it seems to work if the number of elements in each group is equal, but I'm not seeing why. PS:奇怪的是,如果每个组中的元素数量相等,这似乎可行,但是我不明白为什么。

   original before swap: 
    [array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8,  9, 10, 11])]
    original after swap:  
    [array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8,  9, 10, 11])]
    swapped array:
    [[ 0  1  8  3]
    [ 4  5  6  7]
    [ 2  9 10 11]]

When the number of components in each element are not equal, you are having a list of arrays (nested object). 当每个元素中的组件数不相等时,您将获得一个数组列表(嵌套对象)。

When the number of components are equal, then you have a two dimensional array (one single object). 当组件的数量相等时,您将拥有一个二维数组(一个对象)。

The copy you are using is called shallow copy which copies only the top level object (the 2d array in second case, but only the addresses to the arrays in the first case). 您使用的copy称为浅表副本,它仅复制顶层对象(第二种情况下为2d数组,第一种情况下仅复制数组的地址)。 So in the first case your original data also are changed. 因此,在第一种情况下,您的原始数据也会更改。 You should use the copy module: https://docs.python.org/3/library/copy.html 您应该使用copy模块: https : //docs.python.org/3/library/copy.html

a = np.array_split(np.arange(10),3)
a = np.asarray(a)
b = a.copy() -1 +1
print('orginal before swap: ',a)
a_swap = group_swap(b)
print('original after swap: ',a)
print('swapped array: ',a_swap)

From what I can tell, ndarray.copy() takes a shallow copy of the array until some change is made to it. 据我所知, ndarray.copy()会获取数组的浅表副本, 直到对其进行一些更改。 When you call in the variable to the method, it uses the shallow copy of the array, ignoring that it was meant to be changed. 当您在方法中调用变量时,它使用数组的浅表副本,而忽略了要更改的情况。 By changing the variable before passing it through the method, it changes the memory reference of b to a separate place than a. 通过在将变量传递给方法之前更改变量,它会将b的内存引用更改为与a不同的位置。

a = np.asarray(a) is there to cast from a list to a numpy array so that the -1 +1 is a valid operation. a = np.asarray(a)可以从列表转换为numpy数组,因此-1 +1是有效操作。 There are probably a lot of different ways to do the same thing, this just seemed the easiest. 可能有很多不同的方式来做同一件事,这似乎是最简单的。

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

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