Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

API: Deep copy not copying index/columns #4202

hayd opened this Issue Jul 11, 2013 · 13 comments


None yet
3 participants

hayd commented Jul 11, 2013


This means if we change the index in place, e.g. with name:

df1 = df.copy()
df1.index.name = 'ffg'

This changes the name of the df.index.


jreback commented Jul 11, 2013

releated #4039
cc @jtratner

this is the case where reference tracking to the indices would help (but too complicated)

so just force copy indices here


hayd commented Jul 11, 2013

@jreback do you see the index.name thing? apparently not everyone does (my computer is sulking today, so not trusting it): http://stackoverflow.com/a/17591435/1240268


hayd commented Jul 11, 2013

Ah I see, I think that is being done after (which creates a new object):

df2.index = df2.index[::-1]

jtratner commented Jul 16, 2013

Btw - this should be resolved by shallow copying indices, since they are supposed to be mostly immutable. That allows you to change metadata. After #4039, MultiIndex and Index will handle this transparently when copied with view() or anything that triggers __array_finalize__, __setstate__, etc.


hayd commented Jul 31, 2013

@jtratner so this is fixed with #4039 ? (if not, will fix once that's merged)


jtratner commented Jul 31, 2013


@ghost ghost assigned jtratner Sep 9, 2013


jtratner commented Sep 11, 2013

@hayd I believe this is all fixed and can be closed, yes?


hayd commented Sep 12, 2013

@jtratner test is this:

In [11]: df = pd.DataFrame([1])

In [12]: df.index.name = 'foo'

In [13]: df1 = df.copy()

In [14]: df1.index.name = 'bar'

In [15]: df
0    1

jtratner commented Sep 12, 2013

I will fix that.


jtratner commented Sep 12, 2013

@jreback Where is the best opportunity to actually copy an index (both for rows and columns) with the block manager? I think it just needs to be shallow or deep-copied each time and then passed as the new ref_item to the block copying.


jreback commented Sep 12, 2013

right now there is NO deep copying of the index in BM. I think you just need to change BlockManager.copy to something like this:

   def copy(self, deep=True):
        Make deep or shallow copy of BlockManager

        deep : boolean, default True
            If False, return shallow copy (do not copy data)

        copy : BlockManager
        if deep:
             new_axes = [ ax.copy(deep=True) for ax in self.axes ]
             new_axes = list(self.axes)
        return self.apply('copy', axes=new_axes, deep=deep, do_integrity_check=False)

jtratner commented Sep 12, 2013

@jreback ah okay, there it is...now I remember we were hitting this issue before too...need to make sure the ref_items get passed to the copy constructor.

I think this copy needs a separate kwarg for whether index should be deep copied (because, generally, index always needs to be shallow copied).


jreback commented Sep 12, 2013

@jtratner I don't know, I think easist just to copy everything on deep copy?

@jtratner jtratner closed this in #4830 Sep 24, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment