Skip to content

Commit 573e6e4

Browse files
committed
Fixing code check and parameterizing unit tests.
1 parent b1ea8c2 commit 573e6e4

File tree

3 files changed

+31
-23
lines changed

3 files changed

+31
-23
lines changed

doc/source/whatsnew/v2.2.0.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ Other enhancements
192192
- :func:`tseries.api.guess_datetime_format` is now part of the public API (:issue:`54727`)
193193
- :meth:`ExtensionArray._explode` interface method added to allow extension type implementations of the ``explode`` method (:issue:`54833`)
194194
- :meth:`ExtensionArray.duplicated` added to allow extension type implementations of the ``duplicated`` method (:issue:`55255`)
195-
- Allow passing ``pat_dict`` argument to :meth:`pandas.Series.str.replace` (:issue:`51748`)
196195
- Allow passing ``read_only``, ``data_only`` and ``keep_links`` arguments to openpyxl using ``engine_kwargs`` of :func:`read_excel` (:issue:`55027`)
196+
- Allow passing ``repl_kwargs`` argument to :meth:`pandas.Series.str.replace` (:issue:`51748`)
197197
- DataFrame.apply now allows the usage of numba (via ``engine="numba"``) to JIT compile the passed function, allowing for potential speedups (:issue:`54666`)
198198
- Implement masked algorithms for :meth:`Series.value_counts` (:issue:`54984`)
199199
- Improved error message when constructing :class:`Period` with invalid offsets such as "QS" (:issue:`55785`)

pandas/core/strings/accessor.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,7 +1400,7 @@ def replace(
14001400
case: bool | None = None,
14011401
flags: int = 0,
14021402
regex: bool = False,
1403-
pat_dict: dict | None = None,
1403+
repl_kwargs: dict | None = None,
14041404
):
14051405
r"""
14061406
Replace each occurrence of pattern/regex in the Series/Index.
@@ -1435,8 +1435,8 @@ def replace(
14351435
- If False, treats the pattern as a literal string
14361436
- Cannot be set to False if `pat` is a compiled regex or `repl` is
14371437
a callable.
1438-
pat_dict: dict, default None
1439-
<key: value> pairs representing strings to be replaced, and their
1438+
repl_kwargs : dict, default None
1439+
<key : value> pairs representing strings to be replaced, and their
14401440
updated values.
14411441
14421442
Returns
@@ -1460,10 +1460,10 @@ def replace(
14601460
14611461
Examples
14621462
--------
1463-
When `pat_dict` is a dictionary, every key in `pat_dict` is replaced
1463+
When `repl_kwargs` is a dictionary, every key in `repl_kwargs` is replaced
14641464
with its corresponding value:
14651465
1466-
>>> pd.Series(['A', 'B', np.nan]).str.replace(pat_dict={'A': 'a', 'B': 'b'})
1466+
>>> pd.Series(['A', 'B', np.nan]).str.replace(repl_kwargs={'A': 'a', 'B': 'b'})
14671467
0 a
14681468
1 b
14691469
2 NaN
@@ -1531,13 +1531,19 @@ def replace(
15311531
2 NaN
15321532
dtype: object
15331533
"""
1534-
if pat is None and pat_dict is None:
1534+
if pat is None and repl_kwargs is None:
15351535
raise ValueError(
15361536
"Cannot replace a string without specifying a string to be modified."
15371537
)
15381538

1539+
if pat is not None and repl_kwargs is not None:
1540+
raise ValueError(
1541+
"Cannot replace a string using both a pattern and <key : value> "
1542+
"combination."
1543+
)
1544+
15391545
# Check whether repl is valid (GH 13438, GH 15055)
1540-
if not (isinstance(repl, str) or callable(repl)) and pat_dict is None:
1546+
if pat and not (isinstance(repl, str) or callable(repl)):
15411547
raise TypeError("repl must be a string or callable")
15421548

15431549
is_compiled_re = is_re(pat)
@@ -1557,9 +1563,9 @@ def replace(
15571563
if case is None:
15581564
case = True
15591565

1560-
if pat_dict:
1566+
if repl_kwargs:
15611567
res_output = self._data
1562-
for key, value in pat_dict.items():
1568+
for key, value in repl_kwargs.items():
15631569
result = res_output.array._str_replace(
15641570
key, str(value), n=n, case=case, flags=flags, regex=regex
15651571
)

pandas/tests/strings/test_find_replace.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -354,27 +354,29 @@ def test_endswith_nullable_string_dtype(nullable_string_dtype, na):
354354
# --------------------------------------------------------------------------------------
355355
# str.replace
356356
# --------------------------------------------------------------------------------------
357-
def test_replace_dict_invalid(any_string_dtype):
358-
# New replace behavior introduced in #51914
359-
msg = "Cannot replace a string without specifying a string to be modified."
357+
@pytest.mark.parametrize(
358+
"msg, kwargs",
359+
[
360+
("Cannot replace a string without specifying a string to be modified.", {}),
361+
(
362+
"Cannot replace a string using both a pattern and <key : value> "
363+
"combination.",
364+
{"pat": "A*", "repl_kwargs": {"A": "a"}, "regex": True},
365+
),
366+
],
367+
)
368+
def test_replace_dict_invalid(any_string_dtype, msg, kwargs):
369+
# GH 51914
360370
series = Series(data=["A", "B_junk", "C_gunk"], name="my_messy_col")
361371

362372
with pytest.raises(ValueError, match=msg):
363-
series.str.replace()
373+
series.str.replace(**kwargs)
364374

365375

366376
def test_replace_dict(any_string_dtype):
367-
# GH 51914
368-
series = Series(data=["A", "B_junk", "C_gunk"], name="my_messy_col")
369-
new_series1 = series.str.replace(pat_dict={"_gunk": "_junk"})
370-
expected1 = Series(data=["A", "B_junk", "C_junk"], name="my_messy_col")
371-
tm.assert_series_equal(new_series1, expected1)
372-
373-
374-
def test_replace_multi_dict(any_string_dtype):
375377
# GH 51914
376378
series = Series(data=["A", "B", "C"], name="my_messy_col")
377-
new_series = series.str.replace(pat_dict={"A": "a", "B": "b"})
379+
new_series = series.str.replace(repl_kwargs={"A": "a", "B": "b"})
378380
expected = Series(data=["a", "b", "C"], name="my_messy_col")
379381
tm.assert_series_equal(new_series, expected)
380382

0 commit comments

Comments
 (0)