diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index da712f84eb1b5..19c24c9f9bbfb 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -305,7 +305,7 @@ Conversion ^^^^^^^^^^ - Bug in :func:`DataFrame.astype()` when passing a dict of columns and types the `errors` parameter was ignored. (:issue:`25905`) -- +- Bug in :class:`DataFrame` construction from dict, where the index would be sorted instead of using dict insertion order. (:issue:`24859`) - Strings diff --git a/pandas/core/frame.py b/pandas/core/frame.py index fdc99e957e257..aeb051758c184 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -6304,11 +6304,11 @@ def _gotitem(self, Different aggregations per column. - >>> df.agg({'A' : ['sum', 'min'], 'B' : ['min', 'max']}) - A B - max NaN 8.0 - min 1.0 2.0 - sum 12.0 NaN + >>> df.agg({'A' : ['max', 'min'], 'B' : ['min', 'sum']}) + A B + max 7.0 NaN + min 1.0 2.0 + sum NaN 15.0 Aggregate over the columns. diff --git a/pandas/core/indexes/api.py b/pandas/core/indexes/api.py index 6299fc482d0df..b3f220ab4ba83 100644 --- a/pandas/core/indexes/api.py +++ b/pandas/core/indexes/api.py @@ -146,7 +146,8 @@ def _union_indexes(indexes, sort=True): if len(indexes) == 1: result = indexes[0] if isinstance(result, list): - result = Index(sorted(result)) + result = sorted(result) if sort else result + result = Index(result) return result indexes, kind = _sanitize_and_check(indexes) diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index 924e914392839..7a826f7130c50 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -9,7 +9,7 @@ from pandas._libs import lib from pandas._libs.tslibs import IncompatibleFrequency -from pandas.compat import lmap, lrange, raise_with_traceback +from pandas.compat import PY36, lmap, lrange, raise_with_traceback from pandas.core.dtypes.cast import ( construct_1d_arraylike_from_scalar, construct_1d_ndarray_preserving_na, @@ -301,7 +301,7 @@ def extract_index(data): ' an index') if have_series or have_dicts: - index = _union_indexes(indexes) + index = _union_indexes(indexes, sort=not PY36) if have_raw_arrays: lengths = list(set(raw_lengths)) diff --git a/pandas/tests/frame/test_alter_axes.py b/pandas/tests/frame/test_alter_axes.py index f2da432e9d135..e4be94e8f3fed 100644 --- a/pandas/tests/frame/test_alter_axes.py +++ b/pandas/tests/frame/test_alter_axes.py @@ -620,10 +620,9 @@ def test_rename(self, float_frame): # index data = { - 'A': {'foo': 0, 'bar': 1} + 'A': {'bar': 0, 'foo': 1} } - # gets sorted alphabetical df = DataFrame(data) renamed = df.rename(index={'foo': 'bar', 'bar': 'foo'}) tm.assert_index_equal(renamed.index, Index(['foo', 'bar'])) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index e8736e514425f..9e35cff4f526f 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -479,7 +479,8 @@ def test_constructor_subclass_dict(self): dct.update(v.to_dict()) data[k] = dct frame = DataFrame(data) - tm.assert_frame_equal(self.frame.sort_index(), frame) + old_frame = self.frame if PY36 else self.frame.sort_index() + tm.assert_frame_equal(old_frame, frame) def test_constructor_dict_block(self): expected = np.array([[4., 3., 2., 1.]]) @@ -1110,7 +1111,8 @@ def test_constructor_list_of_series(self): sdict = OrderedDict(zip(['x', 'Unnamed 0'], data)) expected = DataFrame.from_dict(sdict, orient='index') - tm.assert_frame_equal(result.sort_index(), expected) + result = result if PY36 else result.sort_index() + tm.assert_frame_equal(result, expected) # none named data = [OrderedDict([['a', 1.5], ['b', 3], ['c', 4], ['d', 6]]), @@ -1245,7 +1247,7 @@ def test_constructor_list_of_namedtuples(self): def test_constructor_orient(self): data_dict = self.mixed_frame.T._series recons = DataFrame.from_dict(data_dict, orient='index') - expected = self.mixed_frame.sort_index() + expected = self.mixed_frame if PY36 else self.mixed_frame.sort_index() tm.assert_frame_equal(recons, expected) # dict of sequence diff --git a/pandas/tests/indexing/multiindex/test_setitem.py b/pandas/tests/indexing/multiindex/test_setitem.py index f8f037dbda46b..58b1158dc5278 100644 --- a/pandas/tests/indexing/multiindex/test_setitem.py +++ b/pandas/tests/indexing/multiindex/test_setitem.py @@ -140,8 +140,8 @@ def test_multiindex_setitem(self): # http://stackoverflow.com/questions/24572040/pandas-access-the-level-of-multiindex-for-inplace-operation df_orig = DataFrame.from_dict({'price': { ('DE', 'Coal', 'Stock'): 2, - ('DE', 'Gas', 'Stock'): 4, ('DE', 'Elec', 'Demand'): 1, + ('DE', 'Gas', 'Stock'): 4, ('FR', 'Gas', 'Stock'): 5, ('FR', 'Solar', 'SupIm'): 0, ('FR', 'Wind', 'SupIm'): 0 diff --git a/pandas/tests/reshape/test_concat.py b/pandas/tests/reshape/test_concat.py index 5080db9354a1f..e70339c7d20fe 100644 --- a/pandas/tests/reshape/test_concat.py +++ b/pandas/tests/reshape/test_concat.py @@ -1588,7 +1588,7 @@ def test_concat_series_axis1(self, sort=sort): s = Series(randn(3), index=['c', 'a', 'b'], name='A') s2 = Series(randn(4), index=['d', 'a', 'b', 'c'], name='B') result = concat([s, s2], axis=1, sort=sort) - expected = DataFrame({'A': s, 'B': s2}) + expected = DataFrame({'A': s, 'B': s2}).sort_index() assert_frame_equal(result, expected) def test_concat_series_axis1_names_applied(self):