diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 358d9447b131d..50aca237b6a12 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -95,6 +95,7 @@ Other enhancements - :meth:`pd.concat` now raises when ``levels`` is given but ``keys`` is None (:issue:`46653`) - :meth:`pd.concat` now raises when ``levels`` contains duplicate values (:issue:`46653`) - Added ``numeric_only`` argument to :meth:`DataFrame.corr`, :meth:`DataFrame.corrwith`, and :meth:`DataFrame.cov` (:issue:`46560`) +- Added ``index`` parameter to :meth:`DataFrame.to_dict` (:issue:`46398`) .. --------------------------------------------------------------------------- .. _whatsnew_150.notable_bug_fixes: diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ceede5fdb5577..b92b0a416b3c5 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1771,7 +1771,7 @@ def to_numpy( return result - def to_dict(self, orient: str = "dict", into=dict): + def to_dict(self, orient: str = "dict", into=dict, index=True): """ Convert the DataFrame to a dictionary. @@ -1807,6 +1807,11 @@ def to_dict(self, orient: str = "dict", into=dict): instance of the mapping type you want. If you want a collections.defaultdict, you must pass it initialized. + index : bool default True + When set to False, method returns a dict without an index key + (and index_names if using orient='tight'). Can only be False + when orient='split' or 'tight'. + Returns ------- dict, list or collections.abc.Mapping @@ -1909,6 +1914,11 @@ def to_dict(self, orient: str = "dict", into=dict): elif orient.startswith("i"): orient = "index" + if not index and orient not in ['split', 'tight']: + raise ValueError( + "'index=False' is only valid when 'orient' is 'split' or 'tight" + ) + if orient == "dict": return into_c((k, v.to_dict(into)) for k, v in self.items()) @@ -1916,36 +1926,65 @@ def to_dict(self, orient: str = "dict", into=dict): return into_c((k, v.tolist()) for k, v in self.items()) elif orient == "split": - return into_c( - ( - ("index", self.index.tolist()), - ("columns", self.columns.tolist()), + if not index: + return into_c( ( - "data", - [ - list(map(maybe_box_native, t)) - for t in self.itertuples(index=False, name=None) - ], - ), + ("columns", self.columns.tolist()), + ( + "data", + [ + list(map(maybe_box_native, t)) + for t in self.itertuples(index=False, name=None) + ], + ), + ) + ) + else: + return into_c( + ( + ("index", self.index.tolist()), + ("columns", self.columns.tolist()), + ( + "data", + [ + list(map(maybe_box_native, t)) + for t in self.itertuples(index=False, name=None) + ], + ), + ) ) - ) elif orient == "tight": - return into_c( - ( - ("index", self.index.tolist()), - ("columns", self.columns.tolist()), + if not index: + return into_c( + ( + ("columns", self.columns.tolist()), + ( + "data", + [ + list(map(maybe_box_native, t)) + for t in self.itertuples(index=False, name=None) + ], + ), + ("column_names", list(self.columns.names)), + ) + ) + else: + return into_c( ( - "data", - [ - list(map(maybe_box_native, t)) - for t in self.itertuples(index=False, name=None) - ], - ), - ("index_names", list(self.index.names)), - ("column_names", list(self.columns.names)), + ("index", self.index.tolist()), + ("columns", self.columns.tolist()), + ( + "data", + [ + list(map(maybe_box_native, t)) + for t in self.itertuples(index=False, name=None) + ], + ), + ("index_names", list(self.index.names)), + ("column_names", list(self.columns.names)), + ) ) - ) elif orient == "series": return into_c((k, v) for k, v in self.items()) diff --git a/pandas/tests/frame/methods/test_to_dict.py b/pandas/tests/frame/methods/test_to_dict.py index 31ea3e582eeb2..0959c7f4018d6 100644 --- a/pandas/tests/frame/methods/test_to_dict.py +++ b/pandas/tests/frame/methods/test_to_dict.py @@ -344,3 +344,16 @@ def test_to_dict_orient_tight(self, index, columns): roundtrip = DataFrame.from_dict(df.to_dict(orient="tight"), orient="tight") tm.assert_frame_equal(df, roundtrip) + + def test_to_dict_index_orient_split(self): + df = DataFrame.from_dict({"a": [1, 3, 4], "b": [9, 11, 12]}) + result = df.to_dict(orient='split', index=False) + expected = {'columns': ['a', 'b'], 'data': [[1, 9], [3, 11], [4, 12]]} + assert (result == expected) + + def test_to_dict_index_orient_tight(self): + df = DataFrame.from_dict({"a": [1, 3, 4], "b": [9, 11, 12]}) + result = df.to_dict(orient='split', index=False) + expected = {'columns': ['a', 'b'], 'data': [ + [1, 9], [3, 11], [4, 12]], 'column_names': [None]} + assert (result == expected)