Skip to content

Commit 35f1eaf

Browse files
committed
DEPR: remove auto broadcasting with a time-series, xref #2304
1 parent dae0b09 commit 35f1eaf

File tree

5 files changed

+79
-52
lines changed

5 files changed

+79
-52
lines changed

doc/source/whatsnew/v0.17.0.txt

+30
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Highlights include:
3737
- Support for ``Series.dt.strftime`` to generate formatted strings for datetime-likes, see :ref:`here <whatsnew_0170.strftime>`
3838
- Development installed versions of pandas will now have ``PEP440`` compliant version strings (:issue:`9518`)
3939
- Support for reading SAS xport files, see :ref:`here <whatsnew_0170.enhancements.sas_xport>`
40+
- Removal of the automatic TimeSeries broadcasting, deprecated since 0.8.0, see :ref:`here <whatsnew_0170.prior_deprecations>`
4041

4142
Check the :ref:`API Changes <whatsnew_0170.api>` and :ref:`deprecations <whatsnew_0170.deprecations>` before updating.
4243

@@ -673,6 +674,35 @@ Removal of prior version deprecations/changes
673674
- Removal of ``na_last`` parameters from ``Series.order()`` and ``Series.sort()``, in favor of ``na_position``, xref (:issue:`5231`)
674675
- Remove of ``percentile_width`` from ``.describe()``, in favor of ``percentiles``. (:issue:`7088`)
675676
- Removal of ``colSpace`` parameter from ``DataFrame.to_string()``, in favor of ``col_space``, circa 0.8.0 version.
677+
- Removal of automatic time-series broadcasting (:issue:`2304`)
678+
679+
.. ipython :: python
680+
681+
np.random.seed(1234)
682+
df = DataFrame(np.random.randn(5,2),columns=list('AB'),index=date_range('20130101',periods=5))
683+
df
684+
685+
Previously
686+
687+
.. code-block:: python
688+
689+
In [3]: df + df.A
690+
FutureWarning: TimeSeries broadcasting along DataFrame index by default is deprecated.
691+
Please use DataFrame.<op> to explicitly broadcast arithmetic operations along the index
692+
693+
Out[3]:
694+
A B
695+
2013-01-01 0.942870 -0.719541
696+
2013-01-02 2.865414 1.120055
697+
2013-01-03 -1.441177 0.166574
698+
2013-01-04 1.719177 0.223065
699+
2013-01-05 0.031393 -2.226989
700+
701+
Current
702+
703+
.. ipython :: python
704+
705+
df.add(df.A,axis='index')
676706

677707
.. _whatsnew_0170.performance:
678708

pandas/core/frame.py

+1-10
Original file line numberDiff line numberDiff line change
@@ -3354,16 +3354,7 @@ def _combine_series_infer(self, other, func, level=None, fill_value=None):
33543354
return self._constructor(data=self._series, index=self.index,
33553355
columns=self.columns)
33563356

3357-
# teeny hack because one does DataFrame + TimeSeries all the time
3358-
if self.index.is_all_dates and other.index.is_all_dates:
3359-
warnings.warn(("TimeSeries broadcasting along DataFrame index "
3360-
"by default is deprecated. Please use "
3361-
"DataFrame.<op> to explicitly broadcast arithmetic "
3362-
"operations along the index"),
3363-
FutureWarning)
3364-
return self._combine_match_index(other, func, level=level, fill_value=fill_value)
3365-
else:
3366-
return self._combine_match_columns(other, func, level=level, fill_value=fill_value)
3357+
return self._combine_match_columns(other, func, level=level, fill_value=fill_value)
33673358

33683359
def _combine_match_index(self, other, func, level=None, fill_value=None):
33693360
left, right = self.align(other, join='outer', axis=0, level=level, copy=False)

pandas/sparse/tests/test_sparse.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -1189,14 +1189,19 @@ def _compare_to_dense(a, b, da, db, op):
11891189
frame['A'].reindex(fidx[::2]),
11901190
SparseSeries([], index=[])]
11911191

1192-
for op in ops:
1192+
for op in opnames:
11931193
_compare_to_dense(frame, frame[::2], frame.to_dense(),
1194-
frame[::2].to_dense(), op)
1194+
frame[::2].to_dense(), getattr(operator, op))
1195+
1196+
# 2304, no auto-broadcasting
11951197
for i, s in enumerate(series):
1198+
f = lambda a, b: getattr(a,op)(b,axis='index')
11961199
_compare_to_dense(frame, s, frame.to_dense(),
1197-
s.to_dense(), op)
1198-
_compare_to_dense(s, frame, s.to_dense(),
1199-
frame.to_dense(), op)
1200+
s.to_dense(), f)
1201+
1202+
# rops are not implemented
1203+
#_compare_to_dense(s, frame, s.to_dense(),
1204+
# frame.to_dense(), f)
12001205

12011206
# cross-sectional operations
12021207
series = [frame.xs(fidx[0]),

pandas/tests/test_frame.py

+34-33
Original file line numberDiff line numberDiff line change
@@ -6039,46 +6039,47 @@ def test_combineSeries(self):
60396039
#added = self.mixed_int + (100*series).astype('int32')
60406040
#_check_mixed_int(added, dtype = dict(A = 'int32', B = 'float64', C = 'int32', D = 'int64'))
60416041

6042-
# TimeSeries
6043-
buf = StringIO()
6044-
tmp = sys.stderr
6045-
sys.stderr = buf
60466042

6047-
try:
6048-
ts = self.tsframe['A']
6049-
added = self.tsframe + ts
6050-
6051-
for key, col in compat.iteritems(self.tsframe):
6052-
result = col + ts
6053-
assert_series_equal(added[key], result, check_names=False)
6054-
self.assertEqual(added[key].name, key)
6055-
if col.name == ts.name:
6056-
self.assertEqual(result.name, 'A')
6057-
else:
6058-
self.assertTrue(result.name is None)
6043+
# TimeSeries
6044+
ts = self.tsframe['A']
6045+
6046+
# 10890
6047+
# we no longer allow auto timeseries broadcasting
6048+
# and require explict broadcasting
6049+
added = self.tsframe.add(ts, axis='index')
6050+
6051+
for key, col in compat.iteritems(self.tsframe):
6052+
result = col + ts
6053+
assert_series_equal(added[key], result, check_names=False)
6054+
self.assertEqual(added[key].name, key)
6055+
if col.name == ts.name:
6056+
self.assertEqual(result.name, 'A')
6057+
else:
6058+
self.assertTrue(result.name is None)
60596059

6060-
smaller_frame = self.tsframe[:-5]
6061-
smaller_added = smaller_frame + ts
6060+
smaller_frame = self.tsframe[:-5]
6061+
smaller_added = smaller_frame.add(ts, axis='index')
60626062

6063-
self.assertTrue(smaller_added.index.equals(self.tsframe.index))
6063+
self.assertTrue(smaller_added.index.equals(self.tsframe.index))
60646064

6065-
smaller_ts = ts[:-5]
6066-
smaller_added2 = self.tsframe + smaller_ts
6067-
assert_frame_equal(smaller_added, smaller_added2)
6065+
smaller_ts = ts[:-5]
6066+
smaller_added2 = self.tsframe.add(smaller_ts, axis='index')
6067+
assert_frame_equal(smaller_added, smaller_added2)
60686068

6069-
# length 0
6070-
result = self.tsframe + ts[:0]
6069+
# length 0, result is all-nan
6070+
result = self.tsframe.add(ts[:0], axis='index')
6071+
expected = DataFrame(np.nan,index=self.tsframe.index,columns=self.tsframe.columns)
6072+
assert_frame_equal(result, expected)
60716073

6072-
# Frame is length 0
6073-
result = self.tsframe[:0] + ts
6074-
self.assertEqual(len(result), 0)
6074+
# Frame is all-nan
6075+
result = self.tsframe[:0].add(ts, axis='index')
6076+
expected = DataFrame(np.nan,index=self.tsframe.index,columns=self.tsframe.columns)
6077+
assert_frame_equal(result, expected)
60756078

6076-
# empty but with non-empty index
6077-
frame = self.tsframe[:1].reindex(columns=[])
6078-
result = frame * ts
6079-
self.assertEqual(len(result), len(ts))
6080-
finally:
6081-
sys.stderr = tmp
6079+
# empty but with non-empty index
6080+
frame = self.tsframe[:1].reindex(columns=[])
6081+
result = frame.mul(ts,axis='index')
6082+
self.assertEqual(len(result), len(ts))
60826083

60836084
def test_combineFunc(self):
60846085
result = self.frame * 2

pandas/tests/test_series.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -4515,10 +4515,10 @@ def test_operators_frame(self):
45154515
# rpow does not work with DataFrame
45164516
df = DataFrame({'A': self.ts})
45174517

4518-
tm.assert_almost_equal(self.ts + self.ts, (self.ts + df)['A'])
4519-
tm.assert_almost_equal(self.ts ** self.ts, (self.ts ** df)['A'])
4520-
tm.assert_almost_equal(self.ts < self.ts, (self.ts < df)['A'])
4521-
tm.assert_almost_equal(self.ts / self.ts, (self.ts / df)['A'])
4518+
tm.assert_almost_equal(self.ts + self.ts, self.ts + df['A'])
4519+
tm.assert_almost_equal(self.ts ** self.ts, self.ts ** df['A'])
4520+
tm.assert_almost_equal(self.ts < self.ts, self.ts < df['A'])
4521+
tm.assert_almost_equal(self.ts / self.ts, self.ts / df['A'])
45224522

45234523
def test_operators_combine(self):
45244524
def _check_fill(meth, op, a, b, fill_value=0):

0 commit comments

Comments
 (0)