Skip to content

Commit ee4cc39

Browse files
committed
ENH: Add StringMethods.capitalize and swapcase
1 parent 587e410 commit ee4cc39

File tree

5 files changed

+71
-6
lines changed

5 files changed

+71
-6
lines changed

doc/source/api.rst

+2
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@ strings and apply several methods to it. These can be acccessed like
521521
:toctree: generated/
522522
:template: autosummary/accessor_method.rst
523523

524+
Series.str.capitalize
524525
Series.str.cat
525526
Series.str.center
526527
Series.str.contains
@@ -549,6 +550,7 @@ strings and apply several methods to it. These can be acccessed like
549550
Series.str.split
550551
Series.str.startswith
551552
Series.str.strip
553+
Series.str.swapcase
552554
Series.str.title
553555
Series.str.upper
554556
Series.str.zfill

doc/source/text.rst

+2
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ Method Summary
233233
:meth:`~Series.str.upper`,Equivalent to ``str.upper``
234234
:meth:`~Series.str.find`,Equivalent to ``str.find``
235235
:meth:`~Series.str.rfind`,Equivalent to ``str.rfind``
236+
:meth:`~Series.str.capicalize`,Equivalent to ``str.capitalize``
237+
:meth:`~Series.str.swapcase`,Equivalent to ``str.swapcase``
236238
:meth:`~Series.str.isalnum`,Equivalent to ``str.isalnum``
237239
:meth:`~Series.str.isalpha`,Equivalent to ``str.isalpha``
238240
:meth:`~Series.str.isdigit`,Equivalent to ``str.isdigit``

doc/source/whatsnew/v0.16.1.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ We recommend that all users upgrade to this version.
1717
Enhancements
1818
~~~~~~~~~~~~
1919

20+
- Added ``StringMethods.capitalize()`` and ``swapcase`` which behave as the same as standard ``str`` (:issue:`9766`)
21+
2022

2123

2224

@@ -58,7 +60,7 @@ Performance Improvements
5860
Bug Fixes
5961
~~~~~~~~~
6062

61-
- Fixed bug (:issue:`9542`) where labels did not appear properly in legend of ``DataFrame.plot()``. Passing ``label=`` args also now works, and series indices are no longer mutated.
63+
- Fixed bug (:issue:`9542`) where labels did not appear properly in legend of ``DataFrame.plot()``. Passing ``label=`` args also now works, and series indices are no longer mutated.
6264

6365

6466

pandas/core/strings.py

+15-5
Original file line numberDiff line numberDiff line change
@@ -1157,18 +1157,28 @@ def rfind(self, sub, start=0, end=None):
11571157
len = _noarg_wrapper(len, docstring=_shared_docs['len'], dtype=int)
11581158

11591159
_shared_docs['casemethods'] = ("""
1160-
Convert strings in array to %s
1160+
Convert strings in array to %(type)s.
1161+
Equivalent to ``str.%(method)s``.
11611162
11621163
Returns
11631164
-------
1164-
uppercase : array
1165+
converted : array
11651166
""")
1167+
_shared_docs['lower'] = dict(type='lowercase', method='lower')
1168+
_shared_docs['upper'] = dict(type='uppercase', method='upper')
1169+
_shared_docs['title'] = dict(type='titlecase', method='title')
1170+
_shared_docs['capitalize'] = dict(type='be capitalized', method='capitalize')
1171+
_shared_docs['swapcase'] = dict(type='be swapcased', method='swapcase')
11661172
lower = _noarg_wrapper(lambda x: x.lower(),
1167-
docstring=_shared_docs['casemethods'] % 'lowercase')
1173+
docstring=_shared_docs['casemethods'] % _shared_docs['lower'])
11681174
upper = _noarg_wrapper(lambda x: x.upper(),
1169-
docstring=_shared_docs['casemethods'] % 'uppercase')
1175+
docstring=_shared_docs['casemethods'] % _shared_docs['upper'])
11701176
title = _noarg_wrapper(lambda x: x.title(),
1171-
docstring=_shared_docs['casemethods'] % 'titlecase')
1177+
docstring=_shared_docs['casemethods'] % _shared_docs['title'])
1178+
capitalize = _noarg_wrapper(lambda x: x.capitalize(),
1179+
docstring=_shared_docs['casemethods'] % _shared_docs['capitalize'])
1180+
swapcase = _noarg_wrapper(lambda x: x.swapcase(),
1181+
docstring=_shared_docs['casemethods'] % _shared_docs['swapcase'])
11721182

11731183
_shared_docs['ismethods'] = ("""
11741184
Check whether all characters in each string in the array are %(type)s.

pandas/tests/test_strings.py

+49
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,53 @@ def test_lower_upper(self):
328328
result = result.str.lower()
329329
tm.assert_series_equal(result, values)
330330

331+
def test_capitalize(self):
332+
values = Series(["FOO", "BAR", NA, "Blah", "blurg"])
333+
result = values.str.capitalize()
334+
exp = Series(["Foo", "Bar", NA, "Blah", "Blurg"])
335+
tm.assert_series_equal(result, exp)
336+
337+
# mixed
338+
mixed = Series(["FOO", NA, "bar", True, datetime.today(),
339+
"blah", None, 1, 2.])
340+
mixed = mixed.str.capitalize()
341+
exp = Series(["Foo", NA, "Bar", NA, NA, "Blah", NA, NA, NA])
342+
tm.assert_almost_equal(mixed, exp)
343+
344+
# unicode
345+
values = Series([u("FOO"), NA, u("bar"), u("Blurg")])
346+
results = values.str.capitalize()
347+
exp = Series([u("Foo"), NA, u("Bar"), u("Blurg")])
348+
tm.assert_series_equal(results, exp)
349+
350+
def test_swapcase(self):
351+
values = Series(["FOO", "BAR", NA, "Blah", "blurg"])
352+
result = values.str.swapcase()
353+
exp = Series(["foo", "bar", NA, "bLAH", "BLURG"])
354+
tm.assert_series_equal(result, exp)
355+
356+
# mixed
357+
mixed = Series(["FOO", NA, "bar", True, datetime.today(),
358+
"Blah", None, 1, 2.])
359+
mixed = mixed.str.swapcase()
360+
exp = Series(["foo", NA, "BAR", NA, NA, "bLAH", NA, NA, NA])
361+
tm.assert_almost_equal(mixed, exp)
362+
363+
# unicode
364+
values = Series([u("FOO"), NA, u("bar"), u("Blurg")])
365+
results = values.str.swapcase()
366+
exp = Series([u("foo"), NA, u("BAR"), u("bLURG")])
367+
tm.assert_series_equal(results, exp)
368+
369+
def test_casemethods(self):
370+
values = ['aaa', 'bbb', 'CCC', 'Dddd', 'eEEE']
371+
s = Series(values)
372+
self.assertEqual(s.str.lower().tolist(), [v.lower() for v in values])
373+
self.assertEqual(s.str.upper().tolist(), [v.upper() for v in values])
374+
self.assertEqual(s.str.title().tolist(), [v.title() for v in values])
375+
self.assertEqual(s.str.capitalize().tolist(), [v.capitalize() for v in values])
376+
self.assertEqual(s.str.swapcase().tolist(), [v.swapcase() for v in values])
377+
331378
def test_replace(self):
332379
values = Series(['fooBAD__barBAD', NA])
333380

@@ -636,6 +683,8 @@ def test_empty_str_methods(self):
636683
tm.assert_series_equal(empty_str, empty.str.istitle())
637684
tm.assert_series_equal(empty_str, empty.str.isnumeric())
638685
tm.assert_series_equal(empty_str, empty.str.isdecimal())
686+
tm.assert_series_equal(empty_str, empty.str.capitalize())
687+
tm.assert_series_equal(empty_str, empty.str.swapcase())
639688

640689
def test_ismethods(self):
641690
values = ['A', 'b', 'Xy', '4', '3A', '', 'TT', '55', '-', ' ']

0 commit comments

Comments
 (0)