diff --git a/doc/source/api.rst b/doc/source/api.rst index b617009fe2f13..af9f8c84388bd 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -521,6 +521,7 @@ strings and apply several methods to it. These can be acccessed like :toctree: generated/ :template: autosummary/accessor_method.rst + Series.str.capitalize Series.str.cat Series.str.center Series.str.contains @@ -549,6 +550,7 @@ strings and apply several methods to it. These can be acccessed like Series.str.split Series.str.startswith Series.str.strip + Series.str.swapcase Series.str.title Series.str.upper Series.str.zfill diff --git a/doc/source/text.rst b/doc/source/text.rst index af32549893dde..2d46b37853cee 100644 --- a/doc/source/text.rst +++ b/doc/source/text.rst @@ -233,6 +233,8 @@ Method Summary :meth:`~Series.str.upper`,Equivalent to ``str.upper`` :meth:`~Series.str.find`,Equivalent to ``str.find`` :meth:`~Series.str.rfind`,Equivalent to ``str.rfind`` + :meth:`~Series.str.capicalize`,Equivalent to ``str.capitalize`` + :meth:`~Series.str.swapcase`,Equivalent to ``str.swapcase`` :meth:`~Series.str.isalnum`,Equivalent to ``str.isalnum`` :meth:`~Series.str.isalpha`,Equivalent to ``str.isalpha`` :meth:`~Series.str.isdigit`,Equivalent to ``str.isdigit`` diff --git a/doc/source/whatsnew/v0.16.1.txt b/doc/source/whatsnew/v0.16.1.txt index 55922091556c1..f8482f8ded184 100644 --- a/doc/source/whatsnew/v0.16.1.txt +++ b/doc/source/whatsnew/v0.16.1.txt @@ -17,6 +17,8 @@ We recommend that all users upgrade to this version. Enhancements ~~~~~~~~~~~~ +- Added ``StringMethods.capitalize()`` and ``swapcase`` which behave as the same as standard ``str`` (:issue:`9766`) + @@ -58,7 +60,7 @@ Performance Improvements Bug Fixes ~~~~~~~~~ -- 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. +- 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. diff --git a/pandas/core/strings.py b/pandas/core/strings.py index 93ad2066d0e12..97f6752fb5851 100644 --- a/pandas/core/strings.py +++ b/pandas/core/strings.py @@ -1157,18 +1157,28 @@ def rfind(self, sub, start=0, end=None): len = _noarg_wrapper(len, docstring=_shared_docs['len'], dtype=int) _shared_docs['casemethods'] = (""" - Convert strings in array to %s + Convert strings in array to %(type)s. + Equivalent to ``str.%(method)s``. Returns ------- - uppercase : array + converted : array """) + _shared_docs['lower'] = dict(type='lowercase', method='lower') + _shared_docs['upper'] = dict(type='uppercase', method='upper') + _shared_docs['title'] = dict(type='titlecase', method='title') + _shared_docs['capitalize'] = dict(type='be capitalized', method='capitalize') + _shared_docs['swapcase'] = dict(type='be swapcased', method='swapcase') lower = _noarg_wrapper(lambda x: x.lower(), - docstring=_shared_docs['casemethods'] % 'lowercase') + docstring=_shared_docs['casemethods'] % _shared_docs['lower']) upper = _noarg_wrapper(lambda x: x.upper(), - docstring=_shared_docs['casemethods'] % 'uppercase') + docstring=_shared_docs['casemethods'] % _shared_docs['upper']) title = _noarg_wrapper(lambda x: x.title(), - docstring=_shared_docs['casemethods'] % 'titlecase') + docstring=_shared_docs['casemethods'] % _shared_docs['title']) + capitalize = _noarg_wrapper(lambda x: x.capitalize(), + docstring=_shared_docs['casemethods'] % _shared_docs['capitalize']) + swapcase = _noarg_wrapper(lambda x: x.swapcase(), + docstring=_shared_docs['casemethods'] % _shared_docs['swapcase']) _shared_docs['ismethods'] = (""" Check whether all characters in each string in the array are %(type)s. diff --git a/pandas/tests/test_strings.py b/pandas/tests/test_strings.py index 727ef39aa35e7..9283be566bd8f 100644 --- a/pandas/tests/test_strings.py +++ b/pandas/tests/test_strings.py @@ -328,6 +328,53 @@ def test_lower_upper(self): result = result.str.lower() tm.assert_series_equal(result, values) + def test_capitalize(self): + values = Series(["FOO", "BAR", NA, "Blah", "blurg"]) + result = values.str.capitalize() + exp = Series(["Foo", "Bar", NA, "Blah", "Blurg"]) + tm.assert_series_equal(result, exp) + + # mixed + mixed = Series(["FOO", NA, "bar", True, datetime.today(), + "blah", None, 1, 2.]) + mixed = mixed.str.capitalize() + exp = Series(["Foo", NA, "Bar", NA, NA, "Blah", NA, NA, NA]) + tm.assert_almost_equal(mixed, exp) + + # unicode + values = Series([u("FOO"), NA, u("bar"), u("Blurg")]) + results = values.str.capitalize() + exp = Series([u("Foo"), NA, u("Bar"), u("Blurg")]) + tm.assert_series_equal(results, exp) + + def test_swapcase(self): + values = Series(["FOO", "BAR", NA, "Blah", "blurg"]) + result = values.str.swapcase() + exp = Series(["foo", "bar", NA, "bLAH", "BLURG"]) + tm.assert_series_equal(result, exp) + + # mixed + mixed = Series(["FOO", NA, "bar", True, datetime.today(), + "Blah", None, 1, 2.]) + mixed = mixed.str.swapcase() + exp = Series(["foo", NA, "BAR", NA, NA, "bLAH", NA, NA, NA]) + tm.assert_almost_equal(mixed, exp) + + # unicode + values = Series([u("FOO"), NA, u("bar"), u("Blurg")]) + results = values.str.swapcase() + exp = Series([u("foo"), NA, u("BAR"), u("bLURG")]) + tm.assert_series_equal(results, exp) + + def test_casemethods(self): + values = ['aaa', 'bbb', 'CCC', 'Dddd', 'eEEE'] + s = Series(values) + self.assertEqual(s.str.lower().tolist(), [v.lower() for v in values]) + self.assertEqual(s.str.upper().tolist(), [v.upper() for v in values]) + self.assertEqual(s.str.title().tolist(), [v.title() for v in values]) + self.assertEqual(s.str.capitalize().tolist(), [v.capitalize() for v in values]) + self.assertEqual(s.str.swapcase().tolist(), [v.swapcase() for v in values]) + def test_replace(self): values = Series(['fooBAD__barBAD', NA]) @@ -636,6 +683,8 @@ def test_empty_str_methods(self): tm.assert_series_equal(empty_str, empty.str.istitle()) tm.assert_series_equal(empty_str, empty.str.isnumeric()) tm.assert_series_equal(empty_str, empty.str.isdecimal()) + tm.assert_series_equal(empty_str, empty.str.capitalize()) + tm.assert_series_equal(empty_str, empty.str.swapcase()) def test_ismethods(self): values = ['A', 'b', 'Xy', '4', '3A', '', 'TT', '55', '-', ' ']