Как я могу скопировать фрейм данных pandas, который содержит список, чтобы будущие изменения в списке в копии не изменили исходный - PullRequest
0 голосов
/ 11 мая 2018
a = pd.DataFrame({'a': [[1,1],[2, 2],[3,3]], 'b':[3,2,1]})

       a    b
0   [1, 1]  3
1   [2, 2]  2
2   [3, 3]  1

После создания глубокой копии

b = copy.deepcopy(a)

Изменение первых элементов списка в b

b.a[0][0] = 0   

       a    b
0   [0, 1]  3
1   [2, 2]  2
2   [3, 3]  1

также изменяет список в

a

       a    b
0   [0, 1]  3
1   [2, 2]  2
2   [3, 3]  1

И df.copy, и copy.deepcopy дают одинаковый результат. Как я могу избежать этого «эффекта цепи» в копии? Или есть способ сделать «более глубокую» копию кадра данных

1 Ответ

0 голосов
/ 11 мая 2018

Итак, я нашел обходной путь:

Сначала создал b новый фрейм данных и скопировал столбец b из фрейма данных a. Затем создал пустой столбец a.

b=pd.DataFrame()
b["b"]=a["b"]
b["a"]=None

Теперь мы можем перебирать строки b и копировать значения столбца a из кадра данных a. Обратите внимание, что мы устанавливаем тип для объекта, чтобы мы могли назначать списки элементам информационного кадра, которые в противном случае будут выбрасывать ValueError

b =b.astype(object) 
for i in range(len(b)):
    b.loc[i,"a"]=copy.deepcopy(a.loc[i,"a"])

Затем внесите необходимые изменения:

b.a[0][0] = 0   

Теперь у нас есть b:

   b       a
0  3  [0, 1]
1  2  [2, 2]
2  1  [3, 3]

И a остались без изменений

        a  b
0  [1, 1]  3
1  [2, 2]  2
2  [3, 3]  1

Теперь давайте посмотрим, в чем может быть проблема с использованием copy. Я использовал функцию id после применения copy, и результаты были:

b=copy.copy(a)
print(id(a)==id(b))                        #False
print(id(a["a"])==id(b["a"]))              #False
print(id(a.loc[0,"a"])==id(b.loc[0,"a"]))  #True

Поскольку в столбце a есть списки, оба кадра данных ссылаются на один и тот же список, и изменение одного влияет на другое. Это была интуиция, лежащая в основе итеративного копирования списков один за другим. Обратите внимание, что такие же результаты были замечены даже при использовании b=copy.deepcopy(a)

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