Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

python - AttributeError: 'str' object has no attribute 'isnumeric'

Slightly confused as I'm positive I've had this working before.

I've created the following method...

def p2f(x):
    if x.strip('%').isnumeric():
        return float(x.strip('%'))/100
    elif x in ['SUPP', 'NEW', 'LOWCOV', 'NA', '']:
        return 0.0
    else:
        return x

but when I run it on my imported CSV file, it produces this error:

AttributeError: 'str' object has no attribute 'isnumeric'

Although I can see that isnumeric is an attribute of str in the documention:

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.str.isnumeric.html?highlight=isnumeric#pandas.Series.str.isnumeric

Unless I'm not interpreting the information correctly?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

str.isnumeric() is only available on Python 3. The error indicates you are using Python 2 instead, where only unicode.isnumeric() exists.

You should really use str.isdecimal(), or better yet, use exception handling:

def p2f(x):
    try:
        return float(x.strip('%'))/100
    except ValueError:
        return 0.0 if x in ('SUPP', 'NEW', 'LOWCOV', 'NA', '') else x

.isnumeric() matches 430 Unicode codepoints in the BMP that float() won't accept, and there are codepoints that .isdigit() returns true for that are also not convertible.

You can generate your own table to check with:

for i in range(2 ** 16):
    c = chr(i)
    if c.isnumeric() or c.isdigit() or c.isdecimal():
        try:
            f = float(c)
        except ValueError:
            f = '<not convertible>'
        di, de, nu = ('u2705' if test() else 'u274c' for test in (c.isdigit, c.isdecimal, c.isnumeric))
        print(f'{c!a:<6} {c}digit: {di}   decimal: {de}   numeric: {nu}  float: {f}')

which produces output like:

'0'    0    digit: ?   decimal: ?   numeric: ?  float: 0.0
'1'    1    digit: ?   decimal: ?   numeric: ?  float: 1.0
'2'    2    digit: ?   decimal: ?   numeric: ?  float: 2.0
'3'    3    digit: ?   decimal: ?   numeric: ?  float: 3.0
'4'    4    digit: ?   decimal: ?   numeric: ?  float: 4.0
'5'    5    digit: ?   decimal: ?   numeric: ?  float: 5.0
'6'    6    digit: ?   decimal: ?   numeric: ?  float: 6.0
'7'    7    digit: ?   decimal: ?   numeric: ?  float: 7.0
'8'    8    digit: ?   decimal: ?   numeric: ?  float: 8.0
'9'    9    digit: ?   decimal: ?   numeric: ?  float: 9.0
'xb2' 2    digit: ?   decimal: ?   numeric: ?  float: <not convertible>
'xb3' 3    digit: ?   decimal: ?   numeric: ?  float: <not convertible>
'xb9' 1    digit: ?   decimal: ?   numeric: ?  float: <not convertible>
'xbc' ?    digit: ?   decimal: ?   numeric: ?  float: <not convertible>
'xbd' ?    digit: ?   decimal: ?   numeric: ?  float: <not convertible>
'xbe' ?    digit: ?   decimal: ?   numeric: ?  float: <not convertible>

and you'll find that only the decimal column has crosses for all non-convertible codepoints.

If you want to use isdecimal() in Python 2, you'd have to decode your bytestring to Unicode first.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...