Skip to content

Commit 3d769c4

Browse files
committed
Merge pull request #10042 from jreback/set
BUG: numericlike set ops on unsupported Indexes
2 parents 4830211 + 7b6d23d commit 3d769c4

File tree

4 files changed

+49
-8
lines changed

4 files changed

+49
-8
lines changed

pandas/core/index.py

+21-4
Original file line numberDiff line numberDiff line change
@@ -1179,17 +1179,18 @@ def argsort(self, *args, **kwargs):
11791179
return result.argsort(*args, **kwargs)
11801180

11811181
def __add__(self, other):
1182-
if isinstance(other, Index):
1182+
if com.is_list_like(other):
11831183
warnings.warn("using '+' to provide set union with Indexes is deprecated, "
11841184
"use '|' or .union()",FutureWarning)
1185+
if isinstance(other, Index):
11851186
return self.union(other)
11861187
return Index(np.array(self) + other)
11871188
__iadd__ = __add__
1189+
__radd__ = __add__
11881190

11891191
def __sub__(self, other):
1190-
if isinstance(other, Index):
1191-
warnings.warn("using '-' to provide set differences with Indexes is deprecated, "
1192-
"use .difference()",FutureWarning)
1192+
warnings.warn("using '-' to provide set differences with Indexes is deprecated, "
1193+
"use .difference()",FutureWarning)
11931194
return self.difference(other)
11941195

11951196
def __and__(self, other):
@@ -2469,6 +2470,21 @@ def _evaluate_compare(self, other):
24692470
cls.__le__ = _make_compare('__le__')
24702471
cls.__ge__ = _make_compare('__ge__')
24712472

2473+
@classmethod
2474+
def _add_numericlike_set_methods_disabled(cls):
2475+
""" add in the numeric set-like methods to disable """
2476+
2477+
def _make_invalid_op(name):
2478+
2479+
def invalid_op(self, other=None):
2480+
raise TypeError("cannot perform {name} with this index type: {typ}".format(name=name,
2481+
typ=type(self)))
2482+
invalid_op.__name__ = name
2483+
return invalid_op
2484+
2485+
cls.__add__ = cls.__radd__ = __iadd__ = _make_invalid_op('__add__')
2486+
cls.__sub__ = __isub__ = _make_invalid_op('__sub__')
2487+
24722488
@classmethod
24732489
def _add_numeric_methods_disabled(cls):
24742490
""" add in numeric methods to disable """
@@ -3148,6 +3164,7 @@ def _add_accessors(cls):
31483164
overwrite=True)
31493165

31503166

3167+
CategoricalIndex._add_numericlike_set_methods_disabled()
31513168
CategoricalIndex._add_numeric_methods_disabled()
31523169
CategoricalIndex._add_logical_methods_disabled()
31533170
CategoricalIndex._add_comparison_methods()

pandas/core/reshape.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ def _convert_level_number(level_num, columns):
612612
new_data[key] = value_slice.ravel()
613613

614614
if len(drop_cols) > 0:
615-
new_columns = new_columns - drop_cols
615+
new_columns = new_columns.difference(drop_cols)
616616

617617
N = len(this)
618618

@@ -1045,7 +1045,7 @@ def check_len(item, name):
10451045
with_dummies = [result]
10461046
for (col, pre, sep) in zip(columns_to_encode, prefix, prefix_sep):
10471047

1048-
dummy = _get_dummies_1d(data[col], prefix=pre, prefix_sep=sep,
1048+
dummy = _get_dummies_1d(data[col], prefix=pre, prefix_sep=sep,
10491049
dummy_na=dummy_na, sparse=sparse)
10501050
with_dummies.append(dummy)
10511051
result = concat(with_dummies, axis=1)

pandas/io/tests/test_pytables.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3613,7 +3613,7 @@ def test_frame_select_complex(self):
36133613

36143614
# invert ok for filters
36153615
result = store.select('df', "~(columns=['A','B'])")
3616-
expected = df.loc[:,df.columns-['A','B']]
3616+
expected = df.loc[:,df.columns.difference(['A','B'])]
36173617
tm.assert_frame_equal(result, expected)
36183618

36193619
# in

pandas/tests/test_index.py

+25-1
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,10 @@ def test_add(self):
686686
# - API change GH 8226
687687
with tm.assert_produces_warning():
688688
self.strIndex + self.strIndex
689+
with tm.assert_produces_warning():
690+
self.strIndex + self.strIndex.tolist()
691+
with tm.assert_produces_warning():
692+
self.strIndex.tolist() + self.strIndex
689693

690694
firstCat = self.strIndex.union(self.dateIndex)
691695
secondCat = self.strIndex.union(self.strIndex)
@@ -772,6 +776,7 @@ def test_difference(self):
772776
assertRaisesRegexp(TypeError, "iterable", first.difference, 0.5)
773777

774778
def test_symmetric_diff(self):
779+
775780
# smoke
776781
idx1 = Index([1, 2, 3, 4], name='idx1')
777782
idx2 = Index([2, 3, 4, 5])
@@ -819,7 +824,7 @@ def test_symmetric_diff(self):
819824

820825
# other isn't iterable
821826
with tm.assertRaises(TypeError):
822-
Index(idx1,dtype='object') - 1
827+
Index(idx1,dtype='object').difference(1)
823828

824829
def test_is_numeric(self):
825830
self.assertFalse(self.dateIndex.is_numeric())
@@ -1488,6 +1493,19 @@ def test_construction_with_dtype(self):
14881493
result = CategoricalIndex(idx, categories=idx, ordered=True)
14891494
tm.assert_index_equal(result, expected, exact=True)
14901495

1496+
def test_disallow_set_ops(self):
1497+
1498+
# GH 10039
1499+
# set ops (+/-) raise TypeError
1500+
idx = pd.Index(pd.Categorical(['a', 'b']))
1501+
1502+
self.assertRaises(TypeError, lambda : idx - idx)
1503+
self.assertRaises(TypeError, lambda : idx + idx)
1504+
self.assertRaises(TypeError, lambda : idx - ['a','b'])
1505+
self.assertRaises(TypeError, lambda : idx + ['a','b'])
1506+
self.assertRaises(TypeError, lambda : ['a','b'] - idx)
1507+
self.assertRaises(TypeError, lambda : ['a','b'] + idx)
1508+
14911509
def test_method_delegation(self):
14921510

14931511
ci = CategoricalIndex(list('aabbca'), categories=list('cabdef'))
@@ -3882,6 +3900,12 @@ def test_difference(self):
38823900
# - API change GH 8226
38833901
with tm.assert_produces_warning():
38843902
first - self.index[-3:]
3903+
with tm.assert_produces_warning():
3904+
self.index[-3:] - first
3905+
with tm.assert_produces_warning():
3906+
self.index[-3:] - first.tolist()
3907+
3908+
self.assertRaises(TypeError, lambda : first.tolist() - self.index[-3:])
38853909

38863910
expected = MultiIndex.from_tuples(sorted(self.index[:-3].values),
38873911
sortorder=0,

0 commit comments

Comments
 (0)