Skip to content

Commit 3583373

Browse files
committed
ENH: add abs method to objects, implement array interface on Panel, SparsePanel #740
1 parent 443dcc5 commit 3583373

File tree

6 files changed

+74
-1
lines changed

6 files changed

+74
-1
lines changed

RELEASE.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ pandas 0.7.0
8787
method to ``Series`` as well (GH #699)
8888
- Add ``isin`` method to Index objects, works just like ``Series.isin`` (GH
8989
#657)
90+
- Implement array interface on Panel so that ufuncs work (re: #740)
9091

9192
**API Changes**
9293

pandas/core/generic.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ def _get_axis(self, axis):
6161
name = self._get_axis_name(axis)
6262
return getattr(self, name)
6363

64+
def abs(self):
65+
"""
66+
Return an object with absolute value taken. Only applicable to objects
67+
that are all numeric
68+
69+
Returns
70+
-------
71+
abs: type of caller
72+
"""
73+
return np.abs(self)
74+
6475
def get(self, key, default=None):
6576
"""
6677
Get item from object for given key (DataFrame column, Panel slice,

pandas/core/panel.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,21 @@ def _init_matrix(self, data, axes, dtype=None, copy=False):
342342
block = make_block(values, items, items)
343343
return BlockManager([block], fixed_axes)
344344

345+
346+
#----------------------------------------------------------------------
347+
# Array interface
348+
349+
def __array__(self, dtype=None):
350+
return self.values
351+
352+
def __array_wrap__(self, result):
353+
return self._constructor(result, items=self.items,
354+
major_axis=self.major_axis,
355+
minor_axis=self.minor_axis, copy=False)
356+
357+
#----------------------------------------------------------------------
358+
# Magic methods
359+
345360
def __repr__(self):
346361
class_name = str(self.__class__)
347362

pandas/sparse/panel.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ class SparsePanel(Panel):
6161

6262
def __init__(self, frames, items=None, major_axis=None, minor_axis=None,
6363
default_fill_value=np.nan, default_kind='block'):
64+
if isinstance(frames, np.ndarray):
65+
new_frames = {}
66+
for item, vals in zip(items, frames):
67+
new_frames[item] = \
68+
SparseDataFrame(vals, index=major_axis,
69+
columns=minor_axis,
70+
default_fill_value=default_fill_value,
71+
default_kind=default_kind)
72+
frames = new_frames
73+
6474
assert(isinstance(frames, dict))
6575

6676
self.default_fill_value = fill_value = default_fill_value
@@ -92,6 +102,13 @@ def _consolidate_inplace(self): # pragma: no cover
92102
# do nothing when DataFrame calls this method
93103
pass
94104

105+
def __array_wrap__(self, result):
106+
return SparsePanel(result, items=self.items,
107+
major_axis=self.major_axis,
108+
minor_axis=self.minor_axis,
109+
default_kind=self.default_kind,
110+
default_fill_value=self.default_fill_value)
111+
95112
@classmethod
96113
def from_dict(cls, data):
97114
"""

pandas/sparse/series.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,20 @@ def __getitem__(self, key):
263263
new_index = Index(self.index.view(ndarray)[key])
264264
return self._constructor(dataSlice, index=new_index, name=self.name)
265265

266+
def abs(self):
267+
"""
268+
Return an object with absolute value taken. Only applicable to objects
269+
that are all numeric
270+
271+
Returns
272+
-------
273+
abs: type of caller
274+
"""
275+
res_sp_values = np.abs(self.sp_values)
276+
return SparseSeries(res_sp_values, index=self.index,
277+
sparse_index=self.sp_index,
278+
fill_value=self.fill_value)
279+
266280
def get(self, label, default=None):
267281
"""
268282
Returns value occupying requested label, default to specified

pandas/tests/test_panel.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,21 @@ def test_get_value(self):
322322
expected = self.panel[item][mnr][mjr]
323323
assert_almost_equal(result, expected)
324324

325+
def test_abs(self):
326+
result = self.panel.abs()
327+
expected = np.abs(self.panel)
328+
self.assert_panel_equal(result, expected)
329+
330+
df = self.panel['ItemA']
331+
result = df.abs()
332+
expected = np.abs(df)
333+
assert_frame_equal(result, expected)
334+
335+
s = df['A']
336+
result = s.abs()
337+
expected = np.abs(s)
338+
assert_series_equal(result, expected)
339+
325340
class CheckIndexing(object):
326341

327342

@@ -966,7 +981,7 @@ def test_group_agg(self):
966981
self.assertRaises(Exception, group_agg, values, bounds, f2)
967982

968983
def test_from_frame_level1_unsorted(self):
969-
tuples = [('MSFT', 3), ('MSFT', 2), ('AAPL', 2),
984+
tuples = [('MSFT', 3), ('MSFT', 2), ('AAPL', 2),
970985
('AAPL', 1), ('MSFT', 1)]
971986
midx = MultiIndex.from_tuples(tuples)
972987
df = DataFrame(np.random.rand(5,4), index=midx)

0 commit comments

Comments
 (0)