Skip to content

Commit f3836c4

Browse files
reidy-pharisbal
authored and
harisbal
committed
ENH: Add columns parameter to from_dict (pandas-dev#19802)
1 parent 69eac1e commit f3836c4

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

doc/source/whatsnew/v0.23.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ Other Enhancements
295295
- ``IntervalIndex.astype`` now supports conversions between subtypes when passed an ``IntervalDtype`` (:issue:`19197`)
296296
- :class:`IntervalIndex` and its associated constructor methods (``from_arrays``, ``from_breaks``, ``from_tuples``) have gained a ``dtype`` parameter (:issue:`19262`)
297297
- Added :func:`SeriesGroupBy.is_monotonic_increasing` and :func:`SeriesGroupBy.is_monotonic_decreasing` (:issue:`17015`)
298+
- :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`)
298299

299300
.. _whatsnew_0230.api_breaking:
300301

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

+19
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,25 @@ 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(OrderedDict([('A', [1, 2]),
1099+
('B', [4, 5])]),
1100+
orient='index', columns=['one', 'two'])
1101+
expected = DataFrame([[1, 2], [4, 5]], index=['A', 'B'],
1102+
columns=['one', 'two'])
1103+
tm.assert_frame_equal(result, expected)
1104+
1105+
msg = "cannot use columns parameter with orient='columns'"
1106+
with tm.assert_raises_regex(ValueError, msg):
1107+
DataFrame.from_dict(dict([('A', [1, 2]), ('B', [4, 5])]),
1108+
orient='columns', columns=['one', 'two'])
1109+
with tm.assert_raises_regex(ValueError, msg):
1110+
DataFrame.from_dict(dict([('A', [1, 2]), ('B', [4, 5])]),
1111+
columns=['one', 'two'])
1112+
10941113
def test_constructor_Series_named(self):
10951114
a = Series([1, 2, 3], index=['a', 'b', 'c'], name='x')
10961115
df = DataFrame(a)

0 commit comments

Comments
 (0)