且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

AttributeError: 'str' 对象没有属性 'isnumeric'

更新时间:2023-12-02 23:27:46

str.isnumeric() 仅适用于 Python 3.该错误表明您使用的是 Python 2,其中只有 unicode.isnumeric() 存在.

你真的应该使用 str.isdecimal(),或者更好的是,使用异常处理:

def p2f(x):尝试:return float(x.strip('%'))/100除了值错误:返回 0.0 如果 x in ('SUPP', 'NEW', 'LOWCOV', 'NA', '') else x

.isnumeric() 匹配 BMP 中 float() 不接受的 430 个 Unicode 代码点,并且有 .isdigit() 返回 true ,因为它也不能转换.

您可以生成自己的表格进行检查:

for i in range(2 ** 16):c = chr(i)如果 c.isnumeric() 或 c.isdigit() 或 c.isdecimal():尝试:f = 浮点数(c)除了值错误:f = ''di, de, nu = ('\u2705' if test() else '\u274c' for test in (c.isdigit, c.isdecimal, c.isnumeric))打印(f'{c!a:<6} {c}\tdigit: {di} 十进制: {de} 数字: {nu} 浮点数: {f}')

产生如下输出:

'0' 0 数字:✅ 十进制:✅ 数字:✅ 浮点:0.0'1' 1 位数字:✅ 十进制:✅ 数字:✅ 浮点数:1.0'2' 2 位数字:✅ 十进制:✅ 数字:✅ 浮点数:2.0'3' 3 位数字:✅ 小数:✅ 数字:✅ 浮点数:3.0'4' 4 位数字:✅ 小数:✅ 数字:✅ 浮点数:4.0'5' 5 位数字:✅ 十进制:✅ 数字:✅ 浮点数:5.0'6' 6 位数字:✅ 十进制:✅ 数字:✅ 浮点数:6.0'7' 7 位数字:✅ 十进制:✅ 数字:✅ 浮点数:7.0'8' 8 位数字:✅ 十进制:✅ 数字:✅ 浮点数:8.0'9' 9 位:✅ 十进制:✅ 数字:✅ 浮点数:9.0'\xb2' ² 数字:✅十进制:❌数字:✅浮点:<不可转换>'\xb3' ³ 数字:✅ 十进制:❌ 数字:✅ 浮点:'\xb9' ¹ 数字:✅ 十进制:❌ 数字:✅ 浮点:<不可转换>'\xbc' ¼ 位:❌ 十进制:❌ 数字:✅ 浮点数:'\xbd' ½ 位:❌ 十进制:❌ 数字:✅ 浮点:<不可转换>'\xbe' ¾ 数字:❌ 十进制:❌ 数字:✅ 浮点数:<不可转换>

并且您会发现只有 decimal 列具有所有不可转换代码点的交叉点.

如果您想在 Python 2 中使用 isdecimal(),您必须首先将您的字节串解码为 Unicode.

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?

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}\tdigit: {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' ²    digit: ✅   decimal: ❌   numeric: ✅  float: <not convertible>
'\xb3' ³    digit: ✅   decimal: ❌   numeric: ✅  float: <not convertible>
'\xb9' ¹    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.