From 262cc2c8c63098ee2466fd7911e1e93eb0dfa174 Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Tue, 4 Jul 2017 16:34:12 -0400 Subject: [PATCH] BUG: rolling.cov with multi-index columns should presever the MI (#16825) xref #16814 (cherry picked from commit 04de578b173c6901e75d24647c49d6a697ceec4b) --- doc/source/whatsnew/v0.20.3.txt | 2 +- pandas/core/indexes/multi.py | 3 +++ pandas/core/window.py | 9 +++++---- pandas/tests/test_window.py | 14 +++++++++++++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/doc/source/whatsnew/v0.20.3.txt b/doc/source/whatsnew/v0.20.3.txt index b2d382a3202a5..409affade712b 100644 --- a/doc/source/whatsnew/v0.20.3.txt +++ b/doc/source/whatsnew/v0.20.3.txt @@ -39,7 +39,7 @@ Bug Fixes - Fixed issue with dataframe scatter plot for categorical data that reports incorrect column key not found when categorical data is used for plotting (:issue:`16199`) - Fixed a pytest marker failing downstream packages' tests suites (:issue:`16680`) - Fixed compat with loading a ``DataFrame`` with a ``PeriodIndex``, from a ``format='fixed'`` HDFStore, in Python 3, that was written in Python 2 (:issue:`16781`) - +- Fixed a bug in failing to compute rolling computations of a column-MultiIndexed ``DataFrame`` (:issue:`16789`, :issue:`16825`) Conversion ^^^^^^^^^^ diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index f30da5b05f8ae..38ae91f10e249 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -1388,6 +1388,9 @@ def __getitem__(self, key): # cannot be sure whether the result will be sorted sortorder = None + if isinstance(key, Index): + key = np.asarray(key) + new_labels = [lab[key] for lab in self.labels] return MultiIndex(levels=self.levels, labels=new_labels, diff --git a/pandas/core/window.py b/pandas/core/window.py index ba7e79944ab0e..b717b794b147b 100644 --- a/pandas/core/window.py +++ b/pandas/core/window.py @@ -831,7 +831,7 @@ def count(self): return self._wrap_results(results, blocks, obj) - _shared_docs['apply'] = dedent(""" + _shared_docs['apply'] = dedent(r""" %(name)s function apply Parameters @@ -1911,7 +1911,8 @@ def dataframe_from_int_dict(data, frame_template): # TODO: not the most efficient (perf-wise) # though not bad code-wise - from pandas import Panel, MultiIndex, Index + from pandas import Panel, MultiIndex + with warnings.catch_warnings(record=True): p = Panel.from_dict(results).swapaxes('items', 'major') if len(p.major_axis) > 0: @@ -1934,8 +1935,8 @@ def dataframe_from_int_dict(data, frame_template): # reset our index names to arg1 names # reset our column names to arg2 names # careful not to mutate the original names - result.columns = Index(result.columns).set_names( - arg2.columns.name) + result.columns = result.columns.set_names( + arg2.columns.names) result.index = result.index.set_names( [arg1.index.name, arg1.columns.name]) diff --git a/pandas/tests/test_window.py b/pandas/tests/test_window.py index cbb3c345a9353..9c3765ffdb716 100644 --- a/pandas/tests/test_window.py +++ b/pandas/tests/test_window.py @@ -455,6 +455,17 @@ def tests_empty_df_rolling(self, roller): result = DataFrame(index=pd.DatetimeIndex([])).rolling(roller).sum() tm.assert_frame_equal(result, expected) + def test_multi_index_names(self): + + # GH 16789, 16825 + cols = pd.MultiIndex.from_product([['A', 'B'], ['C', 'D', 'E']], + names=['1', '2']) + df = pd.DataFrame(np.ones((10, 6)), columns=cols) + result = df.rolling(3).cov() + + tm.assert_index_equal(result.columns, df.columns) + assert result.index.names == [None, '1', '2'] + class TestExpanding(Base): @@ -501,9 +512,10 @@ def test_numpy_compat(self): 'expander', [1, pytest.mark.xfail( reason='GH 16425 expanding with offset not supported')('1s')]) - def tests_empty_df_expanding(self, expander): + def test_empty_df_expanding(self, expander): # GH 15819 Verifies that datetime and integer expanding windows can be # applied to empty DataFrames + expected = DataFrame() result = DataFrame().expanding(expander).sum() tm.assert_frame_equal(result, expected)