Skip to content

Commit 5422807

Browse files
mazayojreback
authored andcommitted
BUG: from_dict ignored order of OrderedDict (#8425) (#26875)
1 parent e607c34 commit 5422807

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

doc/source/whatsnew/v0.25.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,7 @@ Reshaping
11521152
- Bug in :func:`DataFrame.sort_index` where an error is thrown when a multi-indexed ``DataFrame`` is sorted on all levels with the initial level sorted last (:issue:`26053`)
11531153
- Bug in :meth:`Series.nlargest` treats ``True`` as smaller than ``False`` (:issue:`26154`)
11541154
- Bug in :func:`DataFrame.pivot_table` with a :class:`IntervalIndex` as pivot index would raise ``TypeError`` (:issue:`25814`)
1155+
- Bug in which :meth:`DataFrame.from_dict` ignored order of ``OrderedDict`` when ``orient='index'`` (:issue:`8425`).
11551156
- Bug in :meth:`DataFrame.transpose` where transposing a DataFrame with a timezone-aware datetime column would incorrectly raise ``ValueError`` (:issue:`26825`)
11561157
- Bug in :func:`pivot_table` when pivoting a timezone aware column as the ``values`` would remove timezone information (:issue:`14948`)
11571158
- Bug in :func:`merge_asof` when specifying multiple ``by`` columns where one is ``datetime64[ns, tz]`` dtype (:issue:`26649`)

pandas/core/internals/construction.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from pandas._libs import lib
1111
from pandas._libs.tslibs import IncompatibleFrequency, OutOfBoundsDatetime
12+
import pandas.compat as compat
1213
from pandas.compat import raise_with_traceback
1314

1415
from pandas.core.dtypes.cast import (
@@ -338,13 +339,16 @@ def extract_index(data):
338339
have_raw_arrays = False
339340
have_series = False
340341
have_dicts = False
342+
have_ordered = False
341343

342344
for val in data:
343345
if isinstance(val, ABCSeries):
344346
have_series = True
345347
indexes.append(val.index)
346348
elif isinstance(val, dict):
347349
have_dicts = True
350+
if isinstance(val, OrderedDict):
351+
have_ordered = True
348352
indexes.append(list(val.keys()))
349353
elif is_list_like(val) and getattr(val, "ndim", 1) == 1:
350354
have_raw_arrays = True
@@ -353,8 +357,10 @@ def extract_index(data):
353357
if not indexes and not raw_lengths:
354358
raise ValueError("If using all scalar values, you must pass" " an index")
355359

356-
if have_series or have_dicts:
360+
if have_series:
357361
index = _union_indexes(indexes)
362+
elif have_dicts:
363+
index = _union_indexes(indexes, sort=not (compat.PY36 or have_ordered))
358364

359365
if have_raw_arrays:
360366
lengths = list(set(raw_lengths))

pandas/tests/frame/test_constructors.py

+17-3
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,8 @@ def test_constructor_subclass_dict(self, float_frame):
517517
dct.update(v.to_dict())
518518
data[k] = dct
519519
frame = DataFrame(data)
520-
tm.assert_frame_equal(float_frame.sort_index(), frame)
520+
expected = frame.reindex(index=float_frame.index)
521+
tm.assert_frame_equal(float_frame, expected)
521522

522523
def test_constructor_dict_block(self):
523524
expected = np.array([[4.0, 3.0, 2.0, 1.0]])
@@ -1203,7 +1204,7 @@ def test_constructor_list_of_series(self):
12031204

12041205
sdict = OrderedDict(zip(["x", "Unnamed 0"], data))
12051206
expected = DataFrame.from_dict(sdict, orient="index")
1206-
tm.assert_frame_equal(result.sort_index(), expected)
1207+
tm.assert_frame_equal(result, expected)
12071208

12081209
# none named
12091210
data = [
@@ -1342,7 +1343,7 @@ def test_constructor_list_of_namedtuples(self):
13421343
def test_constructor_orient(self, float_string_frame):
13431344
data_dict = float_string_frame.T._series
13441345
recons = DataFrame.from_dict(data_dict, orient="index")
1345-
expected = float_string_frame.sort_index()
1346+
expected = float_string_frame.reindex(index=recons.index)
13461347
tm.assert_frame_equal(recons, expected)
13471348

13481349
# dict of sequence
@@ -1351,6 +1352,19 @@ def test_constructor_orient(self, float_string_frame):
13511352
xp = DataFrame.from_dict(a).T.reindex(list(a.keys()))
13521353
tm.assert_frame_equal(rs, xp)
13531354

1355+
def test_constructor_from_ordered_dict(self):
1356+
# GH8425
1357+
a = OrderedDict(
1358+
[
1359+
("one", OrderedDict([("col_a", "foo1"), ("col_b", "bar1")])),
1360+
("two", OrderedDict([("col_a", "foo2"), ("col_b", "bar2")])),
1361+
("three", OrderedDict([("col_a", "foo3"), ("col_b", "bar3")])),
1362+
]
1363+
)
1364+
expected = DataFrame.from_dict(a, orient="columns").T
1365+
result = DataFrame.from_dict(a, orient="index")
1366+
tm.assert_frame_equal(result, expected)
1367+
13541368
def test_from_dict_columns_parameter(self):
13551369
# GH 18529
13561370
# Test new columns parameter for from_dict that was added to make

0 commit comments

Comments
 (0)