Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: pd.Series.isnumeric() doesn't work on decimal value strings #60750

Open
3 tasks done
sf-dcp opened this issue Jan 21, 2025 · 6 comments
Open
3 tasks done

BUG: pd.Series.isnumeric() doesn't work on decimal value strings #60750

sf-dcp opened this issue Jan 21, 2025 · 6 comments
Assignees
Labels
Docs good first issue Strings String extension data type and string data

Comments

@sf-dcp
Copy link

sf-dcp commented Jan 21, 2025

Pandas version checks

  • I have checked that this issue has not already been reported.

  • I have confirmed this bug exists on the latest version of pandas.

  • I have confirmed this bug exists on the main branch of pandas.

Reproducible Example

import pandas as pd

df = pd.DataFrame({"string_values": ["1", "1.0", "1.1"]})
df.string_values.str.isnumeric()

Issue Description

The series method .isnumeric() only works on integer strings. If a string number is decimal, it will return False. When running the example below, the following is returned:

Image

This is the docs description for the method:

Image

Expected Behavior

Running the method on decimal strings should return True.

Installed Versions

INSTALLED VERSIONS

commit : 0691c5c
python : 3.12.8
python-bits : 64
OS : Linux
OS-release : 5.15.49-linuxkit-pr
Version : #1 SMP PREEMPT Thu May 25 07:27:39 UTC 2023
machine : x86_64
processor :
byteorder : little
LC_ALL : None
LANG : C.UTF-8
LOCALE : C.UTF-8

pandas : 2.2.3
numpy : 2.2.1
pytz : 2024.2
dateutil : 2.9.0.post0
pip : 24.3.1
Cython : None
sphinx : None
IPython : 8.31.0
adbc-driver-postgresql: None
adbc-driver-sqlite : None
bs4 : 4.12.3
blosc : None
bottleneck : None
dataframe-api-compat : None
fastparquet : None
fsspec : None
html5lib : None
hypothesis : None
gcsfs : None
jinja2 : 3.1.5
lxml.etree : 5.3.0
matplotlib : 3.10.0
numba : None
numexpr : None
odfpy : None
openpyxl : 3.1.5
pandas_gbq : None
psycopg2 : 2.9.10
pymysql : None
pyarrow : 18.1.0
pyreadstat : None
pytest : 8.3.4
python-calamine : None
pyxlsb : None
s3fs : None
scipy : 1.15.1
sqlalchemy : 2.0.37
tables : None
tabulate : 0.9.0
xarray : None
xlrd : 2.0.1
xlsxwriter : None
zstandard : None
tzdata : 2024.2
qtpy : None
pyqt5 : None

@sf-dcp sf-dcp added Bug Needs Triage Issue that has not been reviewed by a pandas team member labels Jan 21, 2025
@sf-dcp sf-dcp changed the title BUG: BUG: pd.Series.isnumeric() doesn't work on decimal value strings Jan 21, 2025
@akj2018
Copy link
Contributor

akj2018 commented Jan 22, 2025

Hi @sf-dcp,

This is not a bug in pd.Series.isnumeric() but expected behavior. As per documentation for str.isnumeric(), . (decimal point) is not a numeric character, so strings with decimal points like "1.1" fail the isnumeric() check.

Image

str.isnumeric() method checks if:

  1. All characters in the string are numeric characters.
  2. There is at least one character in the string.

Numeric characters are those with the Unicode property values:

  • Numeric_Type=Digit (e.g., "1", "2", "3")
  • Numeric_Type=Decimal (e.g., standard decimal digits like "1", "2")
  • Numeric_Type=Numeric (e.g., fractions like "⅕", Roman numerals, etc.)

Therefore, . (decimal character) does not have the Unicode numeric property; it's categorized as punctuation.

Solution 01 - Using regex

import re

def is_numeric(string):
    pattern = r'^-?\d+(\.\d+)?$'
    return bool(re.match(pattern, string))

Note:

  • correctly identifies valid numeric strings like "1", "-2.5" and "0.0".
  • rejects invalid strings like "1.0.0", "abc", or empty strings.
  • Does not works for scientific notations, "1e10" returns False

Solution 02 - Using float()

def is_numeric(string):
    try:
        float(string)
        return True
    except ValueError:
        return False

Note:

  • correctly identifies valid numeric strings like "1", "-2.5", "1e10" (scientific notation), and "0.0"
  • rejects invalid strings like "1.0.0", "abc", or empty strings.

Performance Consideration

  • Regex: Slower due to the regex engine's overhead of parsing and matching patterns.
  • Float-based: Faster, as it directly leverages Python’s built-in C-optimized parsing.
# Test dataset (mix of numeric and non-numeric strings)
data = ["1", "123.45", "-987.65", "0", "abc", "123.45.67"] * 1_000_000
  • Regex time: 5.59 seconds
  • Float time: 2.23 seconds

@asishm asishm added the Closing Candidate May be closeable, needs more eyeballs label Jan 22, 2025
@sf-dcp
Copy link
Author

sf-dcp commented Jan 22, 2025

Hi @akj2018, thanks for the prompt reply and suggestions. I think the method name is a bit misleading then where I would expect a string number (with a dot or a negative integer string) to be returned True. But I also understand the logic behind it. At a minimum, I would recommend updating the method docs with a note or warning calling out the method's behavior when it comes to decimal numbers and/or negative numbers. Again, thanks for clarifying.

@rhshadrach
Copy link
Member

rhshadrach commented Jan 22, 2025

Thanks for the report! This mirrors Python behavior:

print("1.2".isnumeric())
# False

The first line of the docstring states:

Check whether all characters in each string are numeric.

Are you saying there might be some confusion as to whether . is a numeric character?

@rhshadrach rhshadrach added Strings String extension data type and string data and removed Needs Triage Issue that has not been reviewed by a pandas team member labels Jan 22, 2025
@sf-dcp
Copy link
Author

sf-dcp commented Jan 24, 2025

@rhshadrach, yep, I may be biased here but I can interpret . being numeric like in a decimal number :) I believe an explicit message about numeric values other than integers (negative and decimal string values) would be beneficial for at least a portion of pandas users.

@rhshadrach
Copy link
Member

I'd be okay with this addition. PRs are welcome!

@rhshadrach rhshadrach added Docs good first issue and removed Bug Closing Candidate May be closeable, needs more eyeballs labels Jan 25, 2025
@akj2018
Copy link
Contributor

akj2018 commented Jan 26, 2025

take

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Docs good first issue Strings String extension data type and string data
Projects
None yet
Development

No branches or pull requests

4 participants