Skip to content

DEPR: make arguments keyword only in to_dict #54630

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Other API changes

Deprecations
~~~~~~~~~~~~
- Deprecated allowing non-keyword arguments in :meth:`DataFrame.to_dict`. (:issue:`54229`)
- Deprecated allowing non-keyword arguments in :meth:`DataFrame.to_hdf` except ``path_or_buf``. (:issue:`54229`)
- Deprecated allowing non-keyword arguments in :meth:`DataFrame.to_json` except ``path_or_buf``. (:issue:`54229`)
- Deprecated allowing non-keyword arguments in :meth:`DataFrame.to_latex` except ``buf``. (:issue:`54229`)
Expand Down
18 changes: 11 additions & 7 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -1924,17 +1924,21 @@ def _create_data_for_split_and_tight_to_dict(
@overload
def to_dict(
self,
*,
orient: Literal["dict", "list", "series", "split", "tight", "index"] = ...,
into: type[dict] = ...,
) -> dict:
...

@overload
def to_dict(self, orient: Literal["records"], into: type[dict] = ...) -> list[dict]:
def to_dict(
self, *, orient: Literal["records"], into: type[dict] = ...
) -> list[dict]:
...

def to_dict(
self,
*,
orient: Literal[
"dict", "list", "series", "split", "tight", "records", "index"
] = "dict",
Expand Down Expand Up @@ -2005,25 +2009,25 @@ def to_dict(

You can specify the return orientation.

>>> df.to_dict('series')
>>> df.to_dict(orient='series')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also keep allowing just orient as positional only keyword, given how we have been using that ourselves in the docs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, should I make that change then?

Copy link
Contributor Author

@rsm-23 rsm-23 Aug 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jorisvandenbossche should I remove the keyword orient from the examples and tests as well?

{'col1': row1 1
row2 2
Name: col1, dtype: int64,
'col2': row1 0.50
row2 0.75
Name: col2, dtype: float64}

>>> df.to_dict('split')
>>> df.to_dict(orient='split')
{'index': ['row1', 'row2'], 'columns': ['col1', 'col2'],
'data': [[1, 0.5], [2, 0.75]]}

>>> df.to_dict('records')
>>> df.to_dict(orient='records')
[{'col1': 1, 'col2': 0.5}, {'col1': 2, 'col2': 0.75}]

>>> df.to_dict('index')
>>> df.to_dict(orient='index')
{'row1': {'col1': 1, 'col2': 0.5}, 'row2': {'col1': 2, 'col2': 0.75}}

>>> df.to_dict('tight')
>>> df.to_dict(orient='tight')
{'index': ['row1', 'row2'], 'columns': ['col1', 'col2'],
'data': [[1, 0.5], [2, 0.75]], 'index_names': [None], 'column_names': [None]}

Expand All @@ -2037,7 +2041,7 @@ def to_dict(
If you want a `defaultdict`, you need to initialize it:

>>> dd = defaultdict(list)
>>> df.to_dict('records', into=dd)
>>> df.to_dict(orient='records', into=dd)
[defaultdict(<class 'list'>, {'col1': 1, 'col2': 0.5}),
defaultdict(<class 'list'>, {'col1': 2, 'col2': 0.75})]
"""
Expand Down
20 changes: 10 additions & 10 deletions pandas/tests/frame/methods/test_to_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,27 @@ def test_to_dict(self, mapping):
for k2, v2 in v.items():
assert v2 == recons_data[k][k2]

recons_data = DataFrame(test_data).to_dict("list", mapping)
recons_data = DataFrame(test_data).to_dict(orient="list", into=mapping)

for k, v in test_data.items():
for k2, v2 in v.items():
assert v2 == recons_data[k][int(k2) - 1]

recons_data = DataFrame(test_data).to_dict("series", mapping)
recons_data = DataFrame(test_data).to_dict(orient="series", into=mapping)

for k, v in test_data.items():
for k2, v2 in v.items():
assert v2 == recons_data[k][k2]

recons_data = DataFrame(test_data).to_dict("split", mapping)
recons_data = DataFrame(test_data).to_dict(orient="split", into=mapping)
expected_split = {
"columns": ["A", "B"],
"index": ["1", "2", "3"],
"data": [[1.0, "1"], [2.0, "2"], [np.nan, "3"]],
}
tm.assert_dict_equal(recons_data, expected_split)

recons_data = DataFrame(test_data).to_dict("records", mapping)
recons_data = DataFrame(test_data).to_dict(orient="records", into=mapping)
expected_records = [
{"A": 1.0, "B": "1"},
{"A": 2.0, "B": "2"},
Expand All @@ -131,15 +131,15 @@ def test_to_dict(self, mapping):
tm.assert_dict_equal(left, right)

# GH#10844
recons_data = DataFrame(test_data).to_dict("index")
recons_data = DataFrame(test_data).to_dict(orient="index")

for k, v in test_data.items():
for k2, v2 in v.items():
assert v2 == recons_data[k2][k]

df = DataFrame(test_data)
df["duped"] = df[df.columns[0]]
recons_data = df.to_dict("index")
recons_data = df.to_dict(orient="index")
comp_data = test_data.copy()
comp_data["duped"] = comp_data[df.columns[0]]
for k, v in comp_data.items():
Expand Down Expand Up @@ -254,14 +254,14 @@ def test_to_dict_index_dtypes(self, into, expected):
def test_to_dict_numeric_names(self):
# GH#24940
df = DataFrame({str(i): [i] for i in range(5)})
result = set(df.to_dict("records")[0].keys())
result = set(df.to_dict(orient="records")[0].keys())
expected = set(df.columns)
assert result == expected

def test_to_dict_wide(self):
# GH#24939
df = DataFrame({(f"A_{i:d}"): [i] for i in range(256)})
result = df.to_dict("records")[0]
result = df.to_dict(orient="records")[0]
expected = {f"A_{i:d}": i for i in range(256)}
assert result == expected

Expand Down Expand Up @@ -310,7 +310,7 @@ def test_to_dict_scalar_constructor_orient_dtype(self, data, expected_dtype):
def test_to_dict_mixed_numeric_frame(self):
# GH 12859
df = DataFrame({"a": [1.0], "b": [9.0]})
result = df.reset_index().to_dict("records")
result = df.reset_index().to_dict(orient="records")
expected = [{"index": 0, "a": 1.0, "b": 9.0}]
assert result == expected

Expand Down Expand Up @@ -395,7 +395,7 @@ def test_to_dict_returns_native_types(self, orient, data, expected_types):
# GH 46751
# Tests we get back native types for all orient types
df = DataFrame(data)
result = df.to_dict(orient)
result = df.to_dict(orient=orient)
if orient == "dict":
assertion_iterator = (
(i, key, value)
Expand Down