Skip to content

Commit affc8b0

Browse files
committed
BUG: (GH4192) Fixed buglet in the broadcasting logic in Series.where
1 parent d5094df commit affc8b0

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

doc/source/release.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ pandas 0.12
324324
(:issue:`4145`, :issue:`4146`)
325325
- Fixed bug in the parsing of microseconds when using the ``format``
326326
argument in ``to_datetime`` (:issue:`4152`)
327+
- Fixed bug in ``Series.where`` where broadcasting a single element input vector
328+
to the length of the series resulted in multiplying the value
329+
inside the input (:issue:`4192`)
327330

328331
pandas 0.11.0
329332
=============

pandas/core/series.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ def where(self, cond, other=nan, inplace=False):
755755
# GH 2745
756756
# treat like a scalar
757757
if len(other) == 1:
758-
other = np.array(other[0]*len(ser))
758+
other = np.repeat(other, len(ser))
759759

760760
# GH 3235
761761
# match True cond to other

pandas/tests/test_series.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,11 +1090,6 @@ def test_where(self):
10901090
expected = Series([0,2])
10911091
assert_series_equal(s,expected)
10921092

1093-
s = Series([1,2])
1094-
s[[True, False]] = [0]
1095-
expected = Series([0,2])
1096-
assert_series_equal(s,expected)
1097-
10981093
# failures
10991094
self.assertRaises(ValueError, s.__setitem__, tuple([[[True, False]]]), [0,2,3])
11001095
self.assertRaises(ValueError, s.__setitem__, tuple([[[True, False]]]), [])
@@ -1142,6 +1137,24 @@ def test_where(self):
11421137
s = Series(np.arange(10))
11431138
mask = s > 5
11441139
self.assertRaises(ValueError, s.__setitem__, mask, ([0]*5,))
1140+
1141+
def test_where_broadcast(self):
1142+
# Test a variety of differently sized series
1143+
for size in range(2, 6):
1144+
# Test a variety of boolean indices
1145+
for selection in [np.resize([True, False, False, False, False], size), # First element should be set
1146+
np.resize([True, False], size), # Set alternating elements]
1147+
np.resize([False], size)]: # No element should be set
1148+
# Test a variety of different numbers as content
1149+
for item in [2.0, np.nan, np.finfo(np.float).max, np.finfo(np.float).min]:
1150+
# Test numpy arrays, lists and tuples as the input to be broadcast
1151+
for arr in [np.array([item]), [item], (item,)]:
1152+
data = np.arange(size, dtype=float)
1153+
s = Series(data)
1154+
s[selection] = arr
1155+
# Construct the expected series by taking the source data or item based on the selection
1156+
expected = Series([item if use_item else data[i] for i, use_item in enumerate(selection)])
1157+
assert_series_equal(s,expected)
11451158

11461159
def test_where_inplace(self):
11471160
s = Series(np.random.randn(5))

0 commit comments

Comments
 (0)