Skip to content

Commit

Permalink
ENH: rename DataFrame axes without copying data
Browse files Browse the repository at this point in the history
  • Loading branch information
wesm committed Sep 21, 2011
1 parent 1ba5625 commit edd9f19
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 16 deletions.
8 changes: 5 additions & 3 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -1346,7 +1346,7 @@ def fillna(self, value=None, method='pad'):
#----------------------------------------------------------------------
# Rename

def rename(self, index=None, columns=None):
def rename(self, index=None, columns=None, copy=True):
"""
Alter index and / or columns using input function or
functions. Function / dict values must be unique (1-to-1). Labels not
Expand All @@ -1358,6 +1358,8 @@ def rename(self, index=None, columns=None):
Transformation to apply to index values
columns : dict-like or function, optional
Transformation to apply to column values
copy : boolean, default True
Also copy underlying data
See also
--------
Expand Down Expand Up @@ -1390,7 +1392,7 @@ def columns_f(x):

self._consolidate_inplace()

result = self.copy()
result = self.copy(deep=copy)

if index is not None:
result._rename_index_inplace(index_f)
Expand All @@ -1405,7 +1407,7 @@ def _rename_index_inplace(self, mapper):
self._series_cache.clear()

def _rename_columns_inplace(self, mapper):
self._data = self._data.rename_items(mapper)
self._data = self._data.rename_items(mapper, copydata=False)
self._series_cache.clear()

#----------------------------------------------------------------------
Expand Down
20 changes: 17 additions & 3 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,9 +397,23 @@ def _values_aggregate(self, func, axis, fill_value, skipna=True):

return result

def copy(self):
"""Make a deep copy of this object"""
return self._constructor(self._data.copy())
def copy(self, deep=True):
"""
Make a copy of this object
Parameters
----------
deep : boolean, default True
Make a deep copy, i.e. also copy data
Returns
-------
copy : type of caller
"""
data = self._data
if deep:
data = data.copy()
return self._constructor(data)

def swaplevel(self, i, j, axis=0):
"""
Expand Down
11 changes: 7 additions & 4 deletions pandas/core/internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,11 @@ def shape(self):
def dtype(self):
return self.values.dtype

def copy(self):
return make_block(self.values.copy(), self.items, self.ref_items)
def copy(self, deep=True):
values = self.values
if deep:
values = values.copy()
return make_block(values, self.items, self.ref_items)

def merge(self, other):
assert(self.ref_items.equals(other.ref_items))
Expand Down Expand Up @@ -682,13 +685,13 @@ def rename_axis(self, mapper, axis=1):
new_axes[axis] = new_axis
return BlockManager(self.blocks, new_axes)

def rename_items(self, mapper):
def rename_items(self, mapper, copydata=True):
new_items = Index([mapper(x) for x in self.items])
new_items._verify_integrity()

new_blocks = []
for block in self.blocks:
newb = block.copy()
newb = block.copy(deep=copydata)
newb.set_ref_items(new_items, maybe_rename=True)
new_blocks.append(newb)
new_axes = list(self.axes)
Expand Down
18 changes: 12 additions & 6 deletions pandas/core/sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,12 +410,15 @@ def astype(self, dtype=None):

return self.copy()

def copy(self):
def copy(self, deep=True):
"""
Make a copy of the SparseSeries. Only the actual sparse values need to
be copied
"""
values = self.sp_values.copy()
if deep:
values = self.sp_values.copy()
else:
values = self.sp_values
return SparseSeries(values, index=self.index,
sparse_index=self.sp_index,
fill_value=self.fill_value)
Expand Down Expand Up @@ -775,12 +778,15 @@ def to_dense(self):
data = dict((k, v.to_dense()) for k, v in self.iteritems())
return DataFrame(data, index=self.index)

def copy(self):
def copy(self, deep=True):
"""
Make a deep copy of this SparseDataFrame
Make a copy of this SparseDataFrame
"""
return SparseDataFrame(self._series, index=self.index,
columns=self.columns,
if deep:
series = self._series.copy()
else:
series = self._series
return SparseDataFrame(series, index=self.index, columns=self.columns,
default_fill_value=self.default_fill_value,
default_kind=self.default_kind)

Expand Down
5 changes: 5 additions & 0 deletions pandas/tests/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -2025,6 +2025,11 @@ def test_rename(self):
renamed = self.frame.T.rename(index={'C' : 'foo', 'D' : 'bar'})
self.assert_(np.array_equal(renamed.index, ['A', 'B', 'foo', 'bar']))

def test_rename_nocopy(self):
renamed = self.frame.rename(columns={'C' : 'foo'}, copy=False)
renamed['foo'] = 1.
self.assert_((self.frame['C'] == 1.).all())

#----------------------------------------------------------------------
# Time series related

Expand Down

0 comments on commit edd9f19

Please sign in to comment.