Обмен элементов в копии массива NumPy - PullRequest
0 голосов
/ 27 августа 2018

У меня есть список / массив пустых массивов, представляющих объекты, разбитые на подгруппы.

Я хотел бы создать копию этого массива, в которой я могу поменять элементы внутри подгрупп и оставить исходные группировки без изменений.

Функция, которую я написал для этого:

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)

Исходя из этого вопроса , я смог поменять элементы. Однако элементы в исходном массиве также меняются местами, как в этом примере.

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)

Что дает:

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

В идеале, массив a должен быть неизменным, и только a_swap показывает замененные элементы. Я надеялся, что создание и работа с копией массива в моей функции поможет, но это не сработало.

Может ли кто-нибудь помочь указать, что мне не хватает? У меня такое чувство, что я потом надену себя.

Спасибо

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

Ответы [ 2 ]

0 голосов
/ 27 августа 2018
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)

Из того, что я могу сказать, ndarray.copy() берет поверхностную копию массива , пока не внесет в него некоторые изменения. Когда вы вызываете переменную для метода, она использует поверхностную копию массива, игнорируя, что она должна быть изменена. Изменяя переменную перед ее передачей через метод, она изменяет ссылку на память в b на отдельное место, чем a.

a = np.asarray(a) предназначен для преобразования из списка в массив numpy, чтобы -1 +1 была допустимой операцией. Вероятно, есть много разных способов сделать одно и то же, но это кажется самым простым.

0 голосов
/ 27 августа 2018

Когда количество компонентов в каждом элементе не равно, у вас есть список массивов (вложенный объект).

Когда количество компонентов равно, у вас есть двумерный массив (один объект).

Используемое copy называется мелкой копией, которая копирует только объект верхнего уровня (массив 2d во втором случае, но только адреса к массивам в первом случае). Так что в первом случае ваши исходные данные также изменены. Вы должны использовать модуль copy: https://docs.python.org/3/library/copy.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...