Skip to content

Commit 3e54611

Browse files
committed
Merge pull request #6339 from cpcloud/replace-bool-fix
BUG: fix bool no-op replace calls
2 parents 5c9a2fd + 3cd050e commit 3e54611

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

doc/source/release.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ Bug Fixes
9292
- ``HDFStore.select_as_coordinates`` and ``select_column`` works where clauses that result in filters (:issue:`6177`)
9393
- Regression in join of non_unique_indexes (:issue:`6329`)
9494
- Issue with groupby ``agg`` with a single function and a a mixed-type frame (:issue:`6337`)
95+
- Bug in ``DataFrame.replace()`` when passing a non- ``bool``
96+
``to_replace`` argument (:issue:`6332`)
9597

9698
pandas 0.13.1
9799
-------------

pandas/core/internals.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,7 @@ def should_store(self, value):
12161216
return (issubclass(value.dtype.type, np.floating) and
12171217
value.dtype == self.dtype)
12181218

1219+
12191220
class ComplexBlock(FloatOrComplexBlock):
12201221
is_complex = True
12211222

@@ -1355,6 +1356,14 @@ def _try_cast(self, element):
13551356
def should_store(self, value):
13561357
return issubclass(value.dtype.type, np.bool_)
13571358

1359+
def replace(self, to_replace, value, inplace=False, filter=None,
1360+
regex=False):
1361+
to_replace_values = np.atleast_1d(to_replace)
1362+
if not np.can_cast(to_replace_values, bool):
1363+
to_replace = to_replace_values
1364+
return super(BoolBlock, self).replace(to_replace, value,
1365+
inplace=inplace, filter=filter,
1366+
regex=regex)
13581367

13591368
class ObjectBlock(Block):
13601369
is_object = True

pandas/tests/test_frame.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7975,7 +7975,7 @@ def test_replace_dict_tuple_list_ordering_remains_the_same(self):
79757975
tm.assert_frame_equal(res2, res3)
79767976
tm.assert_frame_equal(res3, expected)
79777977

7978-
def test_replace_doesnt_replace_with_no_regex(self):
7978+
def test_replace_doesnt_replace_without_regex(self):
79797979
from pandas.compat import StringIO
79807980
raw = """fol T_opp T_Dir T_Enh
79817981
0 1 0 0 vo
@@ -7986,6 +7986,29 @@ def test_replace_doesnt_replace_with_no_regex(self):
79867986
res = df.replace({'\D': 1})
79877987
tm.assert_frame_equal(df, res)
79887988

7989+
def test_replace_bool_with_string(self):
7990+
df = DataFrame({'a': [True, False], 'b': list('ab')})
7991+
result = df.replace(True, 'a')
7992+
expected = DataFrame({'a': ['a', False], 'b': df.b})
7993+
tm.assert_frame_equal(result, expected)
7994+
7995+
def test_replace_pure_bool_with_string_no_op(self):
7996+
df = DataFrame(np.random.rand(2, 2) > 0.5)
7997+
result = df.replace('asdf', 'fdsa')
7998+
tm.assert_frame_equal(df, result)
7999+
8000+
def test_replace_bool_with_bool(self):
8001+
df = DataFrame(np.random.rand(2, 2) > 0.5)
8002+
result = df.replace(False, True)
8003+
expected = DataFrame(np.ones((2, 2), dtype=bool))
8004+
tm.assert_frame_equal(result, expected)
8005+
8006+
def test_replace_with_dict_with_bool_keys(self):
8007+
df = DataFrame({0: [True, False], 1: [False, True]})
8008+
result = df.replace({'asdf': 'asdb', True: 'yes'})
8009+
expected = DataFrame({0: ['yes', False], 1: [False, 'yes']})
8010+
tm.assert_frame_equal(expected, result)
8011+
79898012
def test_combine_multiple_frames_dtypes(self):
79908013
from pandas import concat
79918014

pandas/tests/test_series.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5291,7 +5291,6 @@ def test_replace(self):
52915291
result = ser.replace(Timestamp('20130103'), Timestamp('20120101'))
52925292
assert_series_equal(result, expected)
52935293

5294-
52955294
def test_replace_with_single_list(self):
52965295
ser = Series([0, 1, 2, 3, 4])
52975296
result = ser.replace([1,2,3])
@@ -5307,6 +5306,7 @@ def test_replace_with_single_list(self):
53075306
s.replace([1,2,3],inplace=True,method='crash_cymbal')
53085307
assert_series_equal(s, ser)
53095308

5309+
53105310
def test_replace_mixed_types(self):
53115311
s = Series(np.arange(5),dtype='int64')
53125312

@@ -5349,6 +5349,30 @@ def check_replace(to_rep, val, expected):
53495349
assert_series_equal(r, Series([1.0,2,'a'] +
53505350
dr[3:].tolist(),dtype=object))
53515351

5352+
def test_replace_bool_with_string_no_op(self):
5353+
s = Series([True, False, True])
5354+
result = s.replace('fun', 'in-the-sun')
5355+
tm.assert_series_equal(s, result)
5356+
5357+
def test_replace_bool_with_string(self):
5358+
# nonexistent elements
5359+
s = Series([True, False, True])
5360+
result = s.replace(True, '2u')
5361+
expected = Series(['2u', False, '2u'])
5362+
tm.assert_series_equal(expected, result)
5363+
5364+
def test_replace_bool_with_bool(self):
5365+
s = Series([True, False, True])
5366+
result = s.replace(True, False)
5367+
expected = Series([False] * len(s))
5368+
tm.assert_series_equal(expected, result)
5369+
5370+
def test_replace_with_dict_with_bool_keys(self):
5371+
s = Series([True, False, True])
5372+
result = s.replace({'asdf': 'asdb', True: 'yes'})
5373+
expected = Series(['yes', False, 'yes'])
5374+
tm.assert_series_equal(expected, result)
5375+
53525376
def test_asfreq(self):
53535377
ts = Series([0., 1., 2.], index=[datetime(2009, 10, 30),
53545378
datetime(2009, 11, 30),

0 commit comments

Comments
 (0)