Skip to content

API: rename _prop_attributes to __finalize__ (in NDFrame) #5205

New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 15, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions pandas/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2554,7 +2554,8 @@ def save(obj, path): # TODO remove in 0.13


def _maybe_match_name(a, b):
name = None
if a.name == b.name:
name = a.name
return name
a_name = getattr(a,'name',None)
b_name = getattr(b,'name',None)
if a_name == b_name:
return a_name
return None
89 changes: 50 additions & 39 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ def _single_replace(self, to_replace, method, inplace, limit):
if values.dtype == orig_dtype and inplace:
return

result = pd.Series(values, index=self.index, name=self.name,
dtype=self.dtype)
result = pd.Series(values, index=self.index, dtype=self.dtype).__finalize__(self)

if inplace:
self._data = result._data
Expand All @@ -72,7 +71,7 @@ class NDFrame(PandasObject):
_internal_names = [
'_data', 'name', '_cacher', '_subtyp', '_index', '_default_kind', '_default_fill_value']
_internal_names_set = set(_internal_names)
_prop_attributes = []
_metadata = []

def __init__(self, data, axes=None, copy=False, dtype=None, fastpath=False):

Expand Down Expand Up @@ -413,7 +412,7 @@ def transpose(self, *args, **kwargs):
new_values = self.values.transpose(axes_numbers)
if kwargs.get('copy') or (len(args) and args[-1]):
new_values = new_values.copy()
return self._constructor(new_values, **new_axes)
return self._constructor(new_values, **new_axes).__finalize__(self)

def swapaxes(self, axis1, axis2, copy=True):
"""
Expand All @@ -439,7 +438,7 @@ def swapaxes(self, axis1, axis2, copy=True):
if copy:
new_values = new_values.copy()

return self._constructor(new_values, *new_axes)
return self._constructor(new_values, *new_axes).__finalize__(self)

def pop(self, item):
"""
Expand Down Expand Up @@ -543,7 +542,7 @@ def f(x):
self._clear_item_cache()

else:
return result._propogate_attributes(self)
return result.__finalize__(self)

rename.__doc__ = _shared_docs['rename']

Expand Down Expand Up @@ -655,14 +654,14 @@ def __abs__(self):

def _wrap_array(self, arr, axes, copy=False):
d = self._construct_axes_dict_from(self, axes, copy=copy)
return self._constructor(arr, **d)
return self._constructor(arr, **d).__finalize__(self)

def __array__(self, dtype=None):
return _values_from_object(self)

def __array_wrap__(self, result):
d = self._construct_axes_dict(self._AXIS_ORDERS, copy=False)
return self._constructor(result, **d)
return self._constructor(result, **d).__finalize__(self)

def to_dense(self):
# compat
Expand Down Expand Up @@ -1024,7 +1023,7 @@ def take(self, indices, axis=0, convert=True):
new_data = self._data.reindex_axis(new_items, indexer=indices, axis=0)
else:
new_data = self._data.take(indices, axis=baxis)
return self._constructor(new_data)
return self._constructor(new_data).__finalize__(self)

# TODO: Check if this was clearer in 0.12
def select(self, crit, axis=0):
Expand Down Expand Up @@ -1135,7 +1134,7 @@ def add_prefix(self, prefix):
with_prefix : type of caller
"""
new_data = self._data.add_prefix(prefix)
return self._constructor(new_data)
return self._constructor(new_data).__finalize__(self)

def add_suffix(self, suffix):
"""
Expand All @@ -1150,7 +1149,7 @@ def add_suffix(self, suffix):
with_suffix : type of caller
"""
new_data = self._data.add_suffix(suffix)
return self._constructor(new_data)
return self._constructor(new_data).__finalize__(self)

def sort_index(self, axis=0, ascending=True):
"""
Expand Down Expand Up @@ -1244,7 +1243,8 @@ def reindex(self, *args, **kwargs):
return self

# perform the reindex on the axes
return self._reindex_axes(axes, level, limit, method, fill_value, copy, takeable=takeable)._propogate_attributes(self)
return self._reindex_axes(axes, level, limit,
method, fill_value, copy, takeable=takeable).__finalize__(self)

def _reindex_axes(self, axes, level, limit, method, fill_value, copy, takeable=False):
""" perform the reinxed for all the axes """
Expand Down Expand Up @@ -1332,7 +1332,7 @@ def reindex_axis(self, labels, axis=0, method=None, level=None, copy=True,
new_index, indexer = axis_values.reindex(labels, method, level,
limit=limit, copy_if_needed=True)
return self._reindex_with_indexers({axis: [new_index, indexer]}, method=method, fill_value=fill_value,
limit=limit, copy=copy)._propogate_attributes(self)
limit=limit, copy=copy).__finalize__(self)

def _reindex_with_indexers(self, reindexers, method=None, fill_value=np.nan, limit=None, copy=False, allow_dups=False):
""" allow_dups indicates an internal call here """
Expand Down Expand Up @@ -1370,7 +1370,7 @@ def _reindex_with_indexers(self, reindexers, method=None, fill_value=np.nan, lim
if copy and new_data is self._data:
new_data = new_data.copy()

return self._constructor(new_data)
return self._constructor(new_data).__finalize__(self)

def _reindex_axis(self, new_index, fill_method, axis, copy):
new_data = self._data.reindex_axis(new_index, axis=axis,
Expand All @@ -1379,7 +1379,7 @@ def _reindex_axis(self, new_index, fill_method, axis, copy):
if new_data is self._data and not copy:
return self
else:
return self._constructor(new_data)
return self._constructor(new_data).__finalize__(self)

def filter(self, items=None, like=None, regex=None, axis=None):
"""
Expand Down Expand Up @@ -1421,9 +1421,18 @@ def filter(self, items=None, like=None, regex=None, axis=None):
#----------------------------------------------------------------------
# Attribute access

def _propogate_attributes(self, other):
""" propogate attributes from other to self"""
for name in self._prop_attributes:
def __finalize__(self, other, method=None, **kwargs):
"""
propagate metadata from other to self

Parameters
----------
other : the object from which to get the attributes that we are going to propagate
method : optional, a passed method name ; possibily to take different types
of propagation actions based on this

"""
for name in self._metadata:
object.__setattr__(self, name, getattr(other, name, None))
return self

Expand Down Expand Up @@ -1484,7 +1493,7 @@ def consolidate(self, inplace=False):
cons_data = self._protect_consolidate(f)
if cons_data is self._data:
cons_data = cons_data.copy()
return self._constructor(cons_data)
return self._constructor(cons_data).__finalize__(self)

@property
def _is_mixed_type(self):
Expand All @@ -1504,10 +1513,10 @@ def _protect_consolidate(self, f):
return result

def _get_numeric_data(self):
return self._constructor(self._data.get_numeric_data())
return self._constructor(self._data.get_numeric_data()).__finalize__(self)

def _get_bool_data(self):
return self._constructor(self._data.get_bool_data())
return self._constructor(self._data.get_bool_data()).__finalize__(self)

#----------------------------------------------------------------------
# Internal Interface Methods
Expand Down Expand Up @@ -1584,7 +1593,7 @@ def as_blocks(self, columns=None):
for b in self._data.blocks:
b = b.reindex_items_from(columns or b.items)
bd[str(b.dtype)] = self._constructor(
BlockManager([b], [b.items, self.index]))
BlockManager([b], [b.items, self.index])).__finalize__(self)
return bd

@property
Expand All @@ -1608,7 +1617,7 @@ def astype(self, dtype, copy=True, raise_on_error=True):

mgr = self._data.astype(
dtype, copy=copy, raise_on_error=raise_on_error)
return self._constructor(mgr)._propogate_attributes(self)
return self._constructor(mgr).__finalize__(self)

def copy(self, deep=True):
"""
Expand All @@ -1626,7 +1635,7 @@ def copy(self, deep=True):
data = self._data
if deep:
data = data.copy()
return self._constructor(data)._propogate_attributes(self)
return self._constructor(data).__finalize__(self)

def convert_objects(self, convert_dates=True, convert_numeric=False, copy=True):
"""
Expand All @@ -1642,7 +1651,9 @@ def convert_objects(self, convert_dates=True, convert_numeric=False, copy=True):
-------
converted : asm as input object
"""
return self._constructor(self._data.convert(convert_dates=convert_dates, convert_numeric=convert_numeric, copy=copy))
return self._constructor(self._data.convert(convert_dates=convert_dates,
convert_numeric=convert_numeric,
copy=copy)).__finalize__(self)

#----------------------------------------------------------------------
# Filling NA's
Expand Down Expand Up @@ -1713,7 +1724,7 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,

# fill in 2d chunks
result = dict([ (col,s.fillna(method=method, value=value)) for col, s in compat.iteritems(self) ])
return self._constructor.from_dict(result)
return self._constructor.from_dict(result).__finalize__(self)

# 2d or less
method = com._clean_fill_method(method)
Expand Down Expand Up @@ -1750,7 +1761,7 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
if inplace:
self._data = new_data
else:
return self._constructor(new_data)
return self._constructor(new_data).__finalize__(self)

def ffill(self, axis=0, inplace=False, limit=None, downcast=None):
return self.fillna(method='ffill', axis=axis, inplace=inplace,
Expand Down Expand Up @@ -1991,7 +2002,7 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None,
if inplace:
self._data = new_data
else:
return self._constructor(new_data)
return self._constructor(new_data).__finalize__(self)

def interpolate(self, method='linear', axis=0, limit=None, inplace=False,
downcast='infer', **kwargs):
Expand Down Expand Up @@ -2101,7 +2112,7 @@ def interpolate(self, method='linear', axis=0, limit=None, inplace=False,
else:
self._data = new_data
else:
res = self._constructor(new_data, index=self.index)
res = self._constructor(new_data).__finalize__(self)
if axis == 1:
res = res.T
return res
Expand All @@ -2113,13 +2124,13 @@ def isnull(self):
"""
Return a boolean same-sized object indicating if the values are null
"""
return self.__class__(isnull(self),**self._construct_axes_dict())._propogate_attributes(self)
return self.__class__(isnull(self),**self._construct_axes_dict()).__finalize__(self)

def notnull(self):
"""
Return a boolean same-sized object indicating if the values are not null
"""
return self.__class__(notnull(self),**self._construct_axes_dict())._propogate_attributes(self)
return self.__class__(notnull(self),**self._construct_axes_dict()).__finalize__(self)

def clip(self, lower=None, upper=None, out=None):
"""
Expand Down Expand Up @@ -2484,7 +2495,7 @@ def _align_frame(self, other, join='outer', axis=None, level=None,
left = left.fillna(axis=fill_axis, method=method, limit=limit)
right = right.fillna(axis=fill_axis, method=method, limit=limit)

return left, right
return left.__finalize__(self), right.__finalize__(other)

def _align_series(self, other, join='outer', axis=None, level=None,
copy=True, fill_value=None, method=None, limit=None,
Expand Down Expand Up @@ -2543,7 +2554,7 @@ def _align_series(self, other, join='outer', axis=None, level=None,
right_result.fillna(fill_value, method=method,
limit=limit))
else:
return left_result, right_result
return left_result.__finalize__(self), right_result.__finalize__(other)

def where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
try_cast=False, raise_on_error=True):
Expand Down Expand Up @@ -2680,7 +2691,7 @@ def where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
new_data = self._data.where(
other, cond, align=axis is None, raise_on_error=raise_on_error, try_cast=try_cast)

return self._constructor(new_data)
return self._constructor(new_data).__finalize__(self)

def mask(self, cond):
"""
Expand Down Expand Up @@ -2728,7 +2739,7 @@ def shift(self, periods=1, freq=None, axis=0, **kwds):
else:
return self.tshift(periods, freq, **kwds)

return self._constructor(new_data)
return self._constructor(new_data).__finalize__(self)

def tshift(self, periods=1, freq=None, axis=0, **kwds):
"""
Expand Down Expand Up @@ -2789,7 +2800,7 @@ def tshift(self, periods=1, freq=None, axis=0, **kwds):
new_data = self._data.copy()
new_data.axes[block_axis] = index.shift(periods, offset)

return self._constructor(new_data)
return self._constructor(new_data).__finalize__(self)

def truncate(self, before=None, after=None, copy=True):
"""Truncates a sorted NDFrame before and/or after some particular
Expand Down Expand Up @@ -2864,7 +2875,7 @@ def tz_convert(self, tz, axis=0, copy=True):
new_obj._set_axis(0, new_ax)
self._clear_item_cache()

return new_obj
return new_obj.__finalize__(self)

def tz_localize(self, tz, axis=0, copy=True, infer_dst=False):
"""
Expand Down Expand Up @@ -2902,7 +2913,7 @@ def tz_localize(self, tz, axis=0, copy=True, infer_dst=False):
new_obj._set_axis(0, new_ax)
self._clear_item_cache()

return new_obj
return new_obj.__finalize__(self)

#----------------------------------------------------------------------
# Numeric Methods
Expand Down Expand Up @@ -3128,7 +3139,7 @@ def func(self, axis=None, dtype=None, out=None, skipna=True, **kwargs):

d = self._construct_axes_dict()
d['copy'] = False
return self._constructor(result, **d)._propogate_attributes(self)
return self._constructor(result, **d).__finalize__(self)

func.__name__ = name
return func
Expand Down
8 changes: 4 additions & 4 deletions pandas/core/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ def wrapper(self, other):
if len(self) != len(other):
raise ValueError('Lengths must match to compare')
return self._constructor(na_op(self.values, np.asarray(other)),
index=self.index, name=self.name)
index=self.index).__finalize__(self)
else:

mask = isnull(self)
Expand Down Expand Up @@ -590,7 +590,7 @@ def wrapper(self, other):
else:
# scalars
return self._constructor(na_op(self.values, other),
index=self.index, name=self.name).fillna(False).astype(bool)
index=self.index).fillna(False).astype(bool).__finalize__(self)
return wrapper


Expand Down Expand Up @@ -643,8 +643,8 @@ def f(self, other, level=None, fill_value=None):
return self._binop(self._constructor(other, self.index), op,
level=level, fill_value=fill_value)
else:
return self._constructor(op(self.values, other), self.index,
name=self.name)
return self._constructor(op(self.values, other),
self.index).__finalize__(self)

f.__name__ = name
return f
Expand Down
Loading