7

I have a pd.Series with each cell being a list. I want to make a deep copy of it, however it seems like pd.Series.copy only creates a shallow copy of the values (even though the deep arg is True be default).

example

import pandas as pd

sr = pd.Series([list(range(3)), list(range(3))])
sr_c = sr.copy()
sr[0].append(4)

the copied pd.Series sr_c is being transformed to

0   [0, 1, 2, 4]
1   [0, 1, 2]

I did this and it worked:

from copy import deepcopy
sr_c = sr_c.apply(deepcopy)

however this seems like a hack, is there a better way to do it ?

moshevi
  • 4,999
  • 5
  • 33
  • 50
  • 1
    Seems like this is expected. `When deep=True, data is copied but actual Python objects will not be copied recursively, only the reference to the object. This is in contrast to copy.deepcopy in the Standard Library, which recursively copies object data (see examples below).` So you don't actually deepcopy the lists, which are mutable so it propagates to both `Series`. (This is the last example on the documentation) – ALollz Oct 08 '18 at 18:47

2 Answers2

6

The standard hacky way of deep-copying python objects should work. That is, using pickle.

import pickle
sr2 = pickle.loads(pickle.dumps(sr))
shx2
  • 61,779
  • 13
  • 130
  • 153
  • Would break if some values of the index or entries are not serializable. – Learning is a mess Apr 22 '20 at 15:36
  • 2
    @Learningisamess, correct. That is why this is a hack, but a *fairly useful one*. Pickling+unpickling and deepcopying operations are similar and related, though not equivalent. Although rare, there are types which are deepcopy-able and not pickle-able. More on this [here](https://stackoverflow.com/q/22388854/2096752) – shx2 Apr 22 '20 at 17:28
3

I have used

from copy import deepcopy
sr_copy = pd.Series( deepcopy(sr.to_dict()))

just to be sure that the index is copied recursively too (if needed).

Learning is a mess
  • 7,479
  • 7
  • 35
  • 71