Skip to content

Commit f45cc97

Browse files
authored
ENH: Added dict support for pd.set_option (#61151)
* Added dictionary handling for set_option * precommit * whatsnew * fix test for dictionary input * Updated set_option test * added deprecation warning for multiple option-value pairs * updated test_set_option_multiple to catch deprecation warning * Added example to set_option description * whatsnew deprecation * Fixed docstring error * Removed deprecation warning and whatsnew entry * updated options_context and simplified dictionary handling in set_option * precommit * removed redundant single pair handling
1 parent f2f24a9 commit f45cc97

File tree

3 files changed

+75
-6
lines changed

3 files changed

+75
-6
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Other enhancements
5252
- :class:`Rolling` and :class:`Expanding` now support ``pipe`` method (:issue:`57076`)
5353
- :class:`Series` now supports the Arrow PyCapsule Interface for export (:issue:`59518`)
5454
- :func:`DataFrame.to_excel` argument ``merge_cells`` now accepts a value of ``"columns"`` to only merge :class:`MultiIndex` column header header cells (:issue:`35384`)
55+
- :func:`set_option` now accepts a dictionary of options, simplifying configuration of multiple settings at once (:issue:`61093`)
5556
- :meth:`DataFrame.corrwith` now accepts ``min_periods`` as optional arguments, as in :meth:`DataFrame.corr` and :meth:`Series.corr` (:issue:`9490`)
5657
- :meth:`DataFrame.cummin`, :meth:`DataFrame.cummax`, :meth:`DataFrame.cumprod` and :meth:`DataFrame.cumsum` methods now have a ``numeric_only`` parameter (:issue:`53072`)
5758
- :meth:`DataFrame.ewm` now allows ``adjust=False`` when ``times`` is provided (:issue:`54328`)

pandas/_config/config.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ def set_option(*args) -> None:
199199
200200
Parameters
201201
----------
202-
*args : str | object
203-
Arguments provided in pairs, which will be interpreted as (pattern, value)
204-
pairs.
202+
*args : str | object | dict
203+
Arguments provided in pairs, which will be interpreted as (pattern, value),
204+
or as a single dictionary containing multiple option-value pairs.
205205
pattern: str
206206
Regexp which should match a single option
207207
value: object
@@ -239,6 +239,8 @@ def set_option(*args) -> None:
239239
240240
Examples
241241
--------
242+
Option-Value Pair Input:
243+
242244
>>> pd.set_option("display.max_columns", 4)
243245
>>> df = pd.DataFrame([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
244246
>>> df
@@ -247,8 +249,23 @@ def set_option(*args) -> None:
247249
1 6 7 ... 9 10
248250
[2 rows x 5 columns]
249251
>>> pd.reset_option("display.max_columns")
252+
253+
Dictionary Input:
254+
255+
>>> pd.set_option({"display.max_columns": 4, "display.precision": 1})
256+
>>> df = pd.DataFrame([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
257+
>>> df
258+
0 1 ... 3 4
259+
0 1 2 ... 4 5
260+
1 6 7 ... 9 10
261+
[2 rows x 5 columns]
262+
>>> pd.reset_option("display.max_columns")
263+
>>> pd.reset_option("display.precision")
250264
"""
251-
# must at least 1 arg deal with constraints later
265+
# Handle dictionary input
266+
if len(args) == 1 and isinstance(args[0], dict):
267+
args = tuple(kv for item in args[0].items() for kv in item)
268+
252269
nargs = len(args)
253270
if not nargs or nargs % 2 != 0:
254271
raise ValueError("Must provide an even number of non-keyword arguments")
@@ -440,9 +457,10 @@ def option_context(*args) -> Generator[None]:
440457
441458
Parameters
442459
----------
443-
*args : str | object
460+
*args : str | object | dict
444461
An even amount of arguments provided in pairs which will be
445-
interpreted as (pattern, value) pairs.
462+
interpreted as (pattern, value) pairs. Alternatively, a single
463+
dictionary of {pattern: value} may be provided.
446464
447465
Returns
448466
-------
@@ -471,7 +489,12 @@ def option_context(*args) -> Generator[None]:
471489
>>> from pandas import option_context
472490
>>> with option_context("display.max_rows", 10, "display.max_columns", 5):
473491
... pass
492+
>>> with option_context({"display.max_rows": 10, "display.max_columns": 5}):
493+
... pass
474494
"""
495+
if len(args) == 1 and isinstance(args[0], dict):
496+
args = tuple(kv for item in args[0].items() for kv in item)
497+
475498
if len(args) % 2 != 0 or len(args) < 2:
476499
raise ValueError(
477500
"Provide an even amount of arguments as "

pandas/tests/config/test_config.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,24 @@ def test_set_option_multiple(self):
195195
assert cf.get_option("b.c") is None
196196
assert cf.get_option("b.b") == 10.0
197197

198+
def test_set_option_dict(self):
199+
# GH 61093
200+
201+
cf.register_option("a", 1, "doc")
202+
cf.register_option("b.c", "hullo", "doc2")
203+
cf.register_option("b.b", None, "doc2")
204+
205+
assert cf.get_option("a") == 1
206+
assert cf.get_option("b.c") == "hullo"
207+
assert cf.get_option("b.b") is None
208+
209+
options_dict = {"a": "2", "b.c": None, "b.b": 10.0}
210+
cf.set_option(options_dict)
211+
212+
assert cf.get_option("a") == "2"
213+
assert cf.get_option("b.c") is None
214+
assert cf.get_option("b.b") == 10.0
215+
198216
def test_validation(self):
199217
cf.register_option("a", 1, "doc", validator=cf.is_int)
200218
cf.register_option("d", 1, "doc", validator=cf.is_nonnegative_int)
@@ -377,6 +395,33 @@ def f():
377395

378396
f()
379397

398+
def test_set_ContextManager_dict(self):
399+
def eq(val):
400+
assert cf.get_option("a") == val
401+
assert cf.get_option("b.c") == val
402+
403+
cf.register_option("a", 0)
404+
cf.register_option("b.c", 0)
405+
406+
eq(0)
407+
with cf.option_context({"a": 15, "b.c": 15}):
408+
eq(15)
409+
with cf.option_context({"a": 25, "b.c": 25}):
410+
eq(25)
411+
eq(15)
412+
eq(0)
413+
414+
cf.set_option("a", 17)
415+
cf.set_option("b.c", 17)
416+
eq(17)
417+
418+
# Test that option_context can be used as a decorator too
419+
@cf.option_context({"a": 123, "b.c": 123})
420+
def f():
421+
eq(123)
422+
423+
f()
424+
380425
def test_attribute_access(self):
381426
holder = []
382427

0 commit comments

Comments
 (0)