Skip to content

Commit 44e636a

Browse files
committed
Merge pull request #9439 from sinhrks/string_isnumeric
ENH: Add StringMethods.isnumeric and isdecimal
2 parents c1a0dbc + 0046100 commit 44e636a

File tree

5 files changed

+55
-10
lines changed

5 files changed

+55
-10
lines changed

doc/source/api.rst

+2
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,8 @@ strings and apply several methods to it. These can be acccessed like
559559
Series.str.islower
560560
Series.str.isupper
561561
Series.str.istitle
562+
Series.str.isnumeric
563+
Series.str.isdecimal
562564
Series.str.get_dummies
563565

564566
.. _api.categorical:

doc/source/text.rst

+2
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,5 @@ Method Summary
238238
:meth:`~Series.str.islower`,Equivalent to ``str.islower``
239239
:meth:`~Series.str.isupper`,Equivalent to ``str.isupper``
240240
:meth:`~Series.str.istitle`,Equivalent to ``str.istitle``
241+
:meth:`~Series.str.isnumeric`,Equivalent to ``str.isnumeric``
242+
:meth:`~Series.str.isnumeric`,Equivalent to ``str.isdecimal``

doc/source/whatsnew/v0.16.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ Enhancements
157157
``isupper()``, ``istitle()`` which behave as the same as standard ``str`` (:issue:`9282`)
158158

159159

160-
160+
- Added ``StringMethods.isnumeric`` and ``isdecimal`` which behave as the same as standard ``str`` (:issue:`9439`)
161161
- Added ``StringMethods.ljust()`` and ``rjust()`` which behave as the same as standard ``str`` (:issue:`9352`)
162162
- ``StringMethods.pad()`` and ``center()`` now accept ``fillchar`` option to specify filling character (:issue:`9352`)
163163
- Added ``StringMethods.zfill()`` which behave as the same as standard ``str`` (:issue:`9387`)

pandas/core/strings.py

+22-8
Original file line numberDiff line numberDiff line change
@@ -1096,23 +1096,37 @@ def get_dummies(self, sep='|'):
10961096
docstring=_shared_docs['casemethods'] % 'titlecase')
10971097

10981098
_shared_docs['ismethods'] = ("""
1099-
Check whether all characters in each string in the array are %s
1099+
Check whether all characters in each string in the array are %(type)s.
1100+
Equivalent to ``str.%(method)s``.
11001101
11011102
Returns
11021103
-------
11031104
Series of boolean values
11041105
""")
1106+
_shared_docs['isalnum'] = dict(type='alphanumeric', method='isalnum')
1107+
_shared_docs['isalpha'] = dict(type='alphabetic', method='isalpha')
1108+
_shared_docs['isdigit'] = dict(type='digits', method='isdigit')
1109+
_shared_docs['isspace'] = dict(type='whitespace', method='isspace')
1110+
_shared_docs['islower'] = dict(type='lowercase', method='islower')
1111+
_shared_docs['isupper'] = dict(type='uppercase', method='isupper')
1112+
_shared_docs['istitle'] = dict(type='titlecase', method='istitle')
1113+
_shared_docs['isnumeric'] = dict(type='numeric', method='isnumeric')
1114+
_shared_docs['isdecimal'] = dict(type='decimal', method='isdecimal')
11051115
isalnum = _noarg_wrapper(lambda x: x.isalnum(),
1106-
docstring=_shared_docs['ismethods'] % 'alphanumeric')
1116+
docstring=_shared_docs['ismethods'] % _shared_docs['isalnum'])
11071117
isalpha = _noarg_wrapper(lambda x: x.isalpha(),
1108-
docstring=_shared_docs['ismethods'] % 'alphabetic')
1118+
docstring=_shared_docs['ismethods'] % _shared_docs['isalpha'])
11091119
isdigit = _noarg_wrapper(lambda x: x.isdigit(),
1110-
docstring=_shared_docs['ismethods'] % 'digits')
1120+
docstring=_shared_docs['ismethods'] % _shared_docs['isdigit'])
11111121
isspace = _noarg_wrapper(lambda x: x.isspace(),
1112-
docstring=_shared_docs['ismethods'] % 'whitespace')
1122+
docstring=_shared_docs['ismethods'] % _shared_docs['isspace'])
11131123
islower = _noarg_wrapper(lambda x: x.islower(),
1114-
docstring=_shared_docs['ismethods'] % 'lowercase')
1124+
docstring=_shared_docs['ismethods'] % _shared_docs['islower'])
11151125
isupper = _noarg_wrapper(lambda x: x.isupper(),
1116-
docstring=_shared_docs['ismethods'] % 'uppercase')
1126+
docstring=_shared_docs['ismethods'] % _shared_docs['isupper'])
11171127
istitle = _noarg_wrapper(lambda x: x.istitle(),
1118-
docstring=_shared_docs['ismethods'] % 'titlecase')
1128+
docstring=_shared_docs['ismethods'] % _shared_docs['istitle'])
1129+
isnumeric = _noarg_wrapper(lambda x: compat.u_safe(x).isnumeric(),
1130+
docstring=_shared_docs['ismethods'] % _shared_docs['isnumeric'])
1131+
isdecimal = _noarg_wrapper(lambda x: compat.u_safe(x).isdecimal(),
1132+
docstring=_shared_docs['ismethods'] % _shared_docs['isdecimal'])

pandas/tests/test_strings.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from numpy.testing import assert_array_equal
1515
from numpy.random import randint
1616

17-
from pandas.compat import range, lrange, u
17+
from pandas.compat import range, lrange, u, unichr
1818
import pandas.compat as compat
1919
from pandas import (Index, Series, TimeSeries, DataFrame, isnull, notnull,
2020
bdate_range, date_range, MultiIndex)
@@ -630,6 +630,8 @@ def test_empty_str_methods(self):
630630
tm.assert_series_equal(empty_str, empty.str.islower())
631631
tm.assert_series_equal(empty_str, empty.str.isupper())
632632
tm.assert_series_equal(empty_str, empty.str.istitle())
633+
tm.assert_series_equal(empty_str, empty.str.isnumeric())
634+
tm.assert_series_equal(empty_str, empty.str.isdecimal())
633635

634636
def test_ismethods(self):
635637
values = ['A', 'b', 'Xy', '4', '3A', '', 'TT', '55', '-', ' ']
@@ -659,6 +661,31 @@ def test_ismethods(self):
659661
self.assertEquals(str_s.str.isupper().tolist(), [v.isupper() for v in values])
660662
self.assertEquals(str_s.str.istitle().tolist(), [v.istitle() for v in values])
661663

664+
def test_isnumeric(self):
665+
# 0x00bc: ¼ VULGAR FRACTION ONE QUARTER
666+
# 0x2605: ★ not number
667+
# 0x1378: ፸ ETHIOPIC NUMBER SEVENTY
668+
# 0xFF13: 3 Em 3
669+
values = ['A', '3', unichr(0x00bc), unichr(0x2605),
670+
unichr(0x1378), unichr(0xFF13), 'four']
671+
s = Series(values)
672+
numeric_e = [False, True, True, False, True, True, False]
673+
decimal_e = [False, True, False, False, False, True, False]
674+
tm.assert_series_equal(s.str.isnumeric(), Series(numeric_e))
675+
tm.assert_series_equal(s.str.isdecimal(), Series(decimal_e))
676+
unicodes = [u('A'), u('3'), unichr(0x00bc), unichr(0x2605),
677+
unichr(0x1378), unichr(0xFF13), u('four')]
678+
self.assertEquals(s.str.isnumeric().tolist(), [v.isnumeric() for v in unicodes])
679+
self.assertEquals(s.str.isdecimal().tolist(), [v.isdecimal() for v in unicodes])
680+
681+
values = ['A', np.nan, unichr(0x00bc), unichr(0x2605),
682+
np.nan, unichr(0xFF13), 'four']
683+
s = Series(values)
684+
numeric_e = [False, np.nan, True, False, np.nan, True, False]
685+
decimal_e = [False, np.nan, False, False, np.nan, True, False]
686+
tm.assert_series_equal(s.str.isnumeric(), Series(numeric_e))
687+
tm.assert_series_equal(s.str.isdecimal(), Series(decimal_e))
688+
662689
def test_get_dummies(self):
663690
s = Series(['a|b', 'a|c', np.nan])
664691
result = s.str.get_dummies('|')

0 commit comments

Comments
 (0)