Skip to content

Commit 68d6b47

Browse files
authored
ENH: Add index param to df.to_dict (#48429)
* EHN: Add index param to df.to_dict * Add whatsnew * Move whatsnew * Refactor duplicate code
1 parent 6b396cf commit 68d6b47

File tree

3 files changed

+48
-6
lines changed

3 files changed

+48
-6
lines changed

doc/source/whatsnew/v1.6.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Other enhancements
3131
- :meth:`.GroupBy.quantile` now preserving nullable dtypes instead of casting to numpy dtypes (:issue:`37493`)
3232
- :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is set, the default behaviour of which axis to consider can be overwritten (:issue:`47819`)
3333
- :func:`assert_frame_equal` now shows the first element where the DataFrames differ, analogously to ``pytest``'s output (:issue:`47910`)
34+
- Added ``index`` parameter to :meth:`DataFrame.to_dict` (:issue:`46398`)
3435
-
3536

3637
.. ---------------------------------------------------------------------------

pandas/core/frame.py

+19-6
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,7 @@ def to_dict(
18641864
"dict", "list", "series", "split", "tight", "records", "index"
18651865
] = "dict",
18661866
into: type[dict] = dict,
1867+
index: bool = True,
18671868
) -> dict | list[dict]:
18681869
"""
18691870
Convert the DataFrame to a dictionary.
@@ -1900,6 +1901,13 @@ def to_dict(
19001901
instance of the mapping type you want. If you want a
19011902
collections.defaultdict, you must pass it initialized.
19021903
1904+
index : bool, default True
1905+
Whether to include the index item (and index_names item if `orient`
1906+
is 'tight') in the returned dictionary. Can only be ``False``
1907+
when `orient` is 'split' or 'tight'.
1908+
1909+
.. versionadded:: 1.6.0
1910+
19031911
Returns
19041912
-------
19051913
dict, list or collections.abc.Mapping
@@ -2005,6 +2013,11 @@ def to_dict(
20052013
elif orient.startswith("i"):
20062014
orient = "index"
20072015

2016+
if not index and orient not in ["split", "tight"]:
2017+
raise ValueError(
2018+
"'index=False' is only valid when 'orient' is 'split' or 'tight'"
2019+
)
2020+
20082021
if orient == "dict":
20092022
return into_c((k, v.to_dict(into)) for k, v in self.items())
20102023

@@ -2015,8 +2028,8 @@ def to_dict(
20152028

20162029
elif orient == "split":
20172030
return into_c(
2018-
(
2019-
("index", self.index.tolist()),
2031+
((("index", self.index.tolist()),) if index else ())
2032+
+ (
20202033
("columns", self.columns.tolist()),
20212034
(
20222035
"data",
@@ -2030,8 +2043,8 @@ def to_dict(
20302043

20312044
elif orient == "tight":
20322045
return into_c(
2033-
(
2034-
("index", self.index.tolist()),
2046+
((("index", self.index.tolist()),) if index else ())
2047+
+ (
20352048
("columns", self.columns.tolist()),
20362049
(
20372050
"data",
@@ -2040,9 +2053,9 @@ def to_dict(
20402053
for t in self.itertuples(index=False, name=None)
20412054
],
20422055
),
2043-
("index_names", list(self.index.names)),
2044-
("column_names", list(self.columns.names)),
20452056
)
2057+
+ ((("index_names", list(self.index.names)),) if index else ())
2058+
+ (("column_names", list(self.columns.names)),)
20462059
)
20472060

20482061
elif orient == "series":

pandas/tests/frame/methods/test_to_dict.py

+28
Original file line numberDiff line numberDiff line change
@@ -421,3 +421,31 @@ def test_to_dict_returns_native_types(self, orient, data, expected_types):
421421
for i, key, value in assertion_iterator:
422422
assert value == data[key][i]
423423
assert type(value) is expected_types[key][i]
424+
425+
@pytest.mark.parametrize("orient", ["dict", "list", "series", "records", "index"])
426+
def test_to_dict_index_false_error(self, orient):
427+
# GH#46398
428+
df = DataFrame({"col1": [1, 2], "col2": [3, 4]}, index=["row1", "row2"])
429+
msg = "'index=False' is only valid when 'orient' is 'split' or 'tight'"
430+
with pytest.raises(ValueError, match=msg):
431+
df.to_dict(orient=orient, index=False)
432+
433+
@pytest.mark.parametrize(
434+
"orient, expected",
435+
[
436+
("split", {"columns": ["col1", "col2"], "data": [[1, 3], [2, 4]]}),
437+
(
438+
"tight",
439+
{
440+
"columns": ["col1", "col2"],
441+
"data": [[1, 3], [2, 4]],
442+
"column_names": [None],
443+
},
444+
),
445+
],
446+
)
447+
def test_to_dict_index_false(self, orient, expected):
448+
# GH#46398
449+
df = DataFrame({"col1": [1, 2], "col2": [3, 4]}, index=["row1", "row2"])
450+
result = df.to_dict(orient=orient, index=False)
451+
tm.assert_dict_equal(result, expected)

0 commit comments

Comments
 (0)