diff --git a/doc/source/whatsnew/v0.17.0.txt b/doc/source/whatsnew/v0.17.0.txt index f8efa8ec23300..22ab5c0236dca 100644 --- a/doc/source/whatsnew/v0.17.0.txt +++ b/doc/source/whatsnew/v0.17.0.txt @@ -1032,6 +1032,7 @@ Performance Improvements - Improved performance of ``to_datetime`` when specified format string is ISO8601 (:issue:`10178`) - 2x improvement of ``Series.value_counts`` for float dtype (:issue:`10821`) - Enable ``infer_datetime_format`` in ``to_datetime`` when date components do not have 0 padding (:issue:`11142`) +- Regression from 0.16.1 in constructing ``DataFrame`` from nested dictionary (:issue:`11084`) .. _whatsnew_0170.bug_fixes: diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 9d40cf3921b98..86c382efa8a64 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -52,6 +52,8 @@ from pandas.tseries.period import PeriodIndex from pandas.tseries.index import DatetimeIndex +from pandas.tseries.tdi import TimedeltaIndex + import pandas.core.algorithms as algos import pandas.core.base as base @@ -5400,8 +5402,13 @@ def _homogenize(data, index, dtype=None): v = v.reindex(index, copy=False) else: if isinstance(v, dict): - v = _dict_compat(v) - oindex = index.astype('O') + if oindex is None: + oindex = index.astype('O') + + if isinstance(index, (DatetimeIndex, TimedeltaIndex)): + v = _dict_compat(v) + else: + v = dict(v) v = lib.fast_multiget(v, oindex.values, default=NA) v = _sanitize_array(v, index, dtype=dtype, copy=False, raise_cast_failure=False) diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index 533f8df1d4599..c963222cf4ad9 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -34,7 +34,7 @@ from pandas import (DataFrame, Index, Series, Panel, notnull, isnull, MultiIndex, DatetimeIndex, Timestamp, date_range, read_csv, timedelta_range, Timedelta, CategoricalIndex, - option_context) + option_context, period_range) from pandas.core.dtypes import DatetimeTZDtype import pandas as pd from pandas.parser import CParserError @@ -3061,6 +3061,27 @@ def create_data(constructor): assert_frame_equal(result_timedelta, expected) assert_frame_equal(result_Timedelta, expected) + def test_nested_dict_frame_constructor(self): + rng = period_range('1/1/2000', periods=5) + df = DataFrame(randn(10, 5), columns=rng) + + data = {} + for col in df.columns: + for row in df.index: + data.setdefault(col, {})[row] = df.get_value(row, col) + + result = DataFrame(data, columns=rng) + tm.assert_frame_equal(result, df) + + data = {} + for col in df.columns: + for row in df.index: + data.setdefault(row, {})[col] = df.get_value(row, col) + + result = DataFrame(data, index=rng).T + tm.assert_frame_equal(result, df) + + def _check_basic_constructor(self, empty): "mat: 2d matrix with shpae (3, 2) to input. empty - makes sized objects" mat = empty((2, 3), dtype=float) diff --git a/pandas/tseries/tests/test_period.py b/pandas/tseries/tests/test_period.py index 951bb803ef793..c6fb54ceec644 100644 --- a/pandas/tseries/tests/test_period.py +++ b/pandas/tseries/tests/test_period.py @@ -2075,26 +2075,6 @@ def test_period_set_index_reindex(self): df = df.set_index(idx2) self.assertTrue(df.index.equals(idx2)) - def test_nested_dict_frame_constructor(self): - rng = period_range('1/1/2000', periods=5) - df = DataFrame(randn(10, 5), columns=rng) - - data = {} - for col in df.columns: - for row in df.index: - data.setdefault(col, {})[row] = df.get_value(row, col) - - result = DataFrame(data, columns=rng) - tm.assert_frame_equal(result, df) - - data = {} - for col in df.columns: - for row in df.index: - data.setdefault(row, {})[col] = df.get_value(row, col) - - result = DataFrame(data, index=rng).T - tm.assert_frame_equal(result, df) - def test_frame_to_time_stamp(self): K = 5 index = PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009')