Skip to content

Commit 24ed9ed

Browse files
committed
BUG: implement MultiIndex.diff, add & and | for intersection/union, GH pandas-dev#260
1 parent 89fecc6 commit 24ed9ed

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

RELEASE.rst

+2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ feedback on the library.
114114
- Add inner join option to `DataFrame.join` when joining on key(s) (GH #248)
115115
- Can select set of DataFrame columns by passing a list to `__getitem__` (GH
116116
#253)
117+
- Can use & and | to intersection / union Index objects, respectively
117118

118119
**Improvements to existing features**
119120

@@ -158,6 +159,7 @@ feedback on the library.
158159
- `DataFrame.iteritems` and `DataFrame._series` not assigning name attribute
159160
- Panel.__repr__ raised exception on length-0 major/minor axes
160161
- `DataFrame.join` on key with empty DataFrame produced incorrect columns
162+
- Implemented `MultiIndex.diff` (GH #260)
161163
- `Int64Index.take` and `MultiIndex.take` lost name field, fix downstream
162164
issue GH #262
163165
- `read_csv` / `read_table` fixes

pandas/core/index.py

+26-2
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,15 @@ def __add__(self, other):
259259
__le__ = _indexOp('__le__')
260260
__ge__ = _indexOp('__ge__')
261261

262+
def __sub__(self, other):
263+
return self.diff(other)
264+
265+
def __and__(self, other):
266+
return self.intersection(other)
267+
268+
def __or__(self, other):
269+
return self.union(other)
270+
262271
def union(self, other):
263272
"""
264273
Form the union of two Index objects and sorts if possible
@@ -363,8 +372,6 @@ def diff(self, other):
363372
theDiff = sorted(set(self) - set(otherArr))
364373
return Index(theDiff)
365374

366-
__sub__ = diff
367-
368375
def get_loc(self, key):
369376
"""
370377
Get integer location for requested label
@@ -1514,6 +1521,23 @@ def intersection(self, other):
15141521
uniq_tuples = sorted(set(self_tuples) & set(other_tuples))
15151522
return MultiIndex.from_arrays(zip(*uniq_tuples), sortorder=0)
15161523

1524+
def diff(self, other):
1525+
"""
1526+
Compute sorted set difference of two MultiIndex objects
1527+
1528+
Returns
1529+
-------
1530+
diff : MultiIndex
1531+
"""
1532+
self._assert_can_do_setop(other)
1533+
1534+
if self.equals(other):
1535+
return self[:0]
1536+
1537+
difference = sorted(set(self.values) - set(other.values))
1538+
return MultiIndex.from_tuples(difference, sortorder=0,
1539+
names=self.names)
1540+
15171541
def _assert_can_do_setop(self, other):
15181542
if not isinstance(other, MultiIndex):
15191543
raise TypeError('can only call with other hierarchical '

pandas/tests/test_index.py

+17-2
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ def test_union(self):
863863
piece1 = self.index[:5][::-1]
864864
piece2 = self.index[3:]
865865

866-
the_union = piece1.union(piece2)
866+
the_union = piece1 | piece2
867867

868868
tups = sorted(self.index.get_tuple_index())
869869
expected = MultiIndex.from_tuples(tups)
@@ -884,7 +884,7 @@ def test_intersection(self):
884884
piece1 = self.index[:5][::-1]
885885
piece2 = self.index[3:]
886886

887-
the_int = piece1.intersection(piece2)
887+
the_int = piece1 & piece2
888888
tups = sorted(self.index[3:5].get_tuple_index())
889889
expected = MultiIndex.from_tuples(tups)
890890
self.assert_(the_int.equals(expected))
@@ -896,6 +896,21 @@ def test_intersection(self):
896896
self.assertRaises(TypeError, self.index.intersection,
897897
self.index.get_tuple_index())
898898

899+
def test_diff(self):
900+
first = self.index
901+
result = first - self.index[-3:]
902+
expected = MultiIndex.from_tuples(sorted(self.index[:-3].values),
903+
sortorder=0,
904+
names=self.index.names)
905+
906+
self.assert_(isinstance(result, MultiIndex))
907+
self.assert_(result.equals(expected))
908+
self.assertEqual(result.names, self.index.names)
909+
910+
result = first - first
911+
expected = first[:0]
912+
self.assert_(result.equals(expected))
913+
899914
def test_argsort(self):
900915
result = self.index.argsort()
901916
expected = self.index.get_tuple_index().argsort()

0 commit comments

Comments
 (0)