Skip to content

Commit f7a0879

Browse files
committed
ENH: Add columns parameter to from_dict
1 parent 740ad9a commit f7a0879

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

doc/source/whatsnew/v0.23.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ Other API Changes
589589
- :func:`Series.to_csv` now accepts a ``compression`` argument that works in the same way as the ``compression`` argument in :func:`DataFrame.to_csv` (:issue:`18958`)
590590
- Set operations (union, difference...) on :class:`IntervalIndex` with incompatible index types will now raise a ``TypeError`` rather than a ``ValueError`` (:issue:`19329`)
591591
- :class:`DateOffset` objects render more simply, e.g. ``<DateOffset: days=1>`` instead of ``<DateOffset: kwds={'days': 1}>`` (:issue:`19403`)
592+
- :func:`DataFrame.from_dict` now accepts a ``columns`` argument that can be used to specify the column names when ``orient='index'`` is used (:issue:`18529`)
592593

593594
.. _whatsnew_0230.deprecations:
594595

pandas/core/frame.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ def dot(self, other):
876876
# IO methods (to / from other formats)
877877

878878
@classmethod
879-
def from_dict(cls, data, orient='columns', dtype=None):
879+
def from_dict(cls, data, orient='columns', dtype=None, columns=None):
880880
"""
881881
Construct DataFrame from dict of array-like or dicts
882882
@@ -890,12 +890,17 @@ def from_dict(cls, data, orient='columns', dtype=None):
890890
(default). Otherwise if the keys should be rows, pass 'index'.
891891
dtype : dtype, default None
892892
Data type to force, otherwise infer
893+
columns: list, default None
894+
Column labels to use when orient='index'. Raises a ValueError
895+
if used with orient='columns'
896+
897+
.. versionadded:: 0.23.0
893898
894899
Returns
895900
-------
896901
DataFrame
897902
"""
898-
index, columns = None, None
903+
index = None
899904
orient = orient.lower()
900905
if orient == 'index':
901906
if len(data) > 0:
@@ -904,7 +909,11 @@ def from_dict(cls, data, orient='columns', dtype=None):
904909
data = _from_nested_dict(data)
905910
else:
906911
data, index = list(data.values()), list(data.keys())
907-
elif orient != 'columns': # pragma: no cover
912+
elif orient == 'columns':
913+
if columns is not None:
914+
raise ValueError("cannot use columns parameter with "
915+
"orient='columns'")
916+
else: # pragma: no cover
908917
raise ValueError('only recognize index or columns for orient')
909918

910919
return cls(data, index=index, columns=columns, dtype=dtype)

pandas/tests/frame/test_constructors.py

+18
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,24 @@ def test_constructor_orient(self):
10911091
xp = DataFrame.from_dict(a).T.reindex(list(a.keys()))
10921092
tm.assert_frame_equal(rs, xp)
10931093

1094+
def test_from_dict_columns_parameter(self):
1095+
# GH 18529
1096+
# Test new columns parameter for from_dict that was added to make
1097+
# from_items(..., orient='index', columns=[...]) easier to replicate
1098+
result = DataFrame.from_dict(dict([('A', [1, 2]), ('B', [4, 5])]),
1099+
orient='index', columns=['one', 'two'])
1100+
expected = DataFrame([[1, 2], [4, 5]], index=['A', 'B'],
1101+
columns=['one', 'two'])
1102+
tm.assert_frame_equal(result, expected)
1103+
1104+
msg = "cannot use columns parameter with orient='columns'"
1105+
with tm.assert_raises_regex(ValueError, msg):
1106+
DataFrame.from_dict(dict([('A', [1, 2]), ('B', [4, 5])]),
1107+
orient='columns', columns=['one', 'two'])
1108+
with tm.assert_raises_regex(ValueError, msg):
1109+
DataFrame.from_dict(dict([('A', [1, 2]), ('B', [4, 5])]),
1110+
columns=['one', 'two'])
1111+
10941112
def test_constructor_Series_named(self):
10951113
a = Series([1, 2, 3], index=['a', 'b', 'c'], name='x')
10961114
df = DataFrame(a)

0 commit comments

Comments
 (0)