【问题标题】:Identifying numeric and array types in numpy在 numpy 中识别数字和数组类型
【发布时间】:2015-09-08 00:54:41
【问题描述】:

numpy 中是否有一个现有函数可以告诉我一个值是数字类型还是 numpy 数组?我正在编写一些需要处理几种不同表示形式的数字的数据处理代码(“数字”是指可以使用标准算术运算符 +、-、*、/、* 操作的数字量的任何表示形式) *)。

我正在寻找的一些行为示例

>>> is_numeric(5)
True
>>> is_numeric(123.345)
True
>>> is_numeric('123.345')
False
>>> is_numeric(decimal.Decimal('123.345'))
True
>>> is_numeric(True)
False
>>> is_numeric([1, 2, 3])
False
>>> is_numeric([1, '2', 3])
False
>>> a = numpy.array([1, 2.3, 4.5, 6.7, 8.9])
>>> is_numeric(a)
True
>>> is_numeric(a[0])
True
>>> is_numeric(a[1])
True
>>> is_numeric(numpy.array([numpy.array([1]), numpy.array([2])])
True
>>> is_numeric(numpy.array(['1'])
False

如果不存在这样的函数,我知道写一个应该不难,比如

isinstance(n, (int, float, decimal.Decimal, numpy.number, numpy.ndarray))

但是我应该在列表中包括其他数字类型吗?

【问题讨论】:

  • 应该返回什么is_numeric([1,2,3])is_numeric([1, '2', 3])
  • 在这两种情况下都是错误的。我会将其编辑到问题中。
  • numpy.array([numpy.array([1]), numpy.array([2])]) 呢?
  • “通过尝试做数学测试”不会捕获 bool 值或它们的 numpy 数组。

标签: python numpy


【解决方案1】:

正如其他人所回答的那样,除了您提到的数字类型之外,可能还有其他数字类型。 一种方法是明确检查您想要的功能,例如

# Python 2
def is_numeric(obj):
    attrs = ['__add__', '__sub__', '__mul__', '__div__', '__pow__']
    return all(hasattr(obj, attr) for attr in attrs)

# Python 3
def is_numeric(obj):
    attrs = ['__add__', '__sub__', '__mul__', '__truediv__', '__pow__']
    return all(hasattr(obj, attr) for attr in attrs)

这适用于您的所有示例,除了最后一个,numpy.array(['1'])。这是因为numpy.ndarray 具有用于数值运算的特殊方法,但如果您尝试将它们不适当地用于字符串或对象数组,则会引发 TypeError。您可以为此添加显式检查

 ... and not (isinstance(obj, ndarray) and obj.dtype.kind in 'OSU')

这可能已经足够了。

但是...您永远无法100%确定某人不会定义具有相同行为的另一种类型,因此更安全的方法是实际尝试进行计算并捕获例外,类似

def is_numeric_paranoid(obj):
    try:
        obj+obj, obj-obj, obj*obj, obj**obj, obj/obj
    except ZeroDivisionError:
        return True
    except Exception:
        return False
    else:
        return True

但取决于您计划调用使用它的频率以及使用哪些参数,这可能不实用(它可能会很慢,例如使用大型数组)。

【讨论】:

  • True,False 和它们的 numpy 数组在这些测试中看起来像数字,因此它们需要包含在 and not 子句中;假设您不想对它们进行数学运算。
【解决方案2】:

另外,numpy 有numpy.isreal 和其他类似的功能(numpy.is + Tab 应该列出它们)。

他们都有自己有趣的角落案例,但其中一个可能很有用。

【讨论】:

  • np.isreal(np.array(['bar', 'baz'], dtype='O')) 返回array([ True, True], dtype=bool)。那些 dtype='O's 在 pandas 文本列中很常见,例如..
  • 另外,np.isreal(np.nan) 返回 true。应该改名为isnoncomplex...
【解决方案3】:

一般来说,处理未知类型的灵活、快速和 Python 式的方法是对它们执行一些操作并捕获无效类型的异常。

try:
    a = 5+'5'
except TypeError:
    print "Oops"

在我看来,这种方法比特殊封装某些函数来确定绝对类型确定性更容易。

【讨论】:

  • 这不是问题的答案,但我完全同意。
  • @JF,没错,但我仍然喜欢这个问题的答案。我认为 str*int 错误会比 is_numeric 函数更容易编写。另外,考虑到 IIRC,没有定义其他数学运算,其中两个操作数是 str 和 int。
  • True,False(以及它们的 numpy 数组)在此测试中“看起来像数字”。
【解决方案4】:

您的is_numeric 定义不明确。请参阅我的 cmets 来回答您的问题。

其他数字类型可能是:longcomplexfractions.Fractionnumpy.bool_numpy.ubyte、...

operator.isNumberType() 为 Python 数字返回 Truenumpy.array

从 Python 2.6 开始,您可以使用 isinstance(d, numbers.Number) 代替已弃用的 operator.isNumberType()

通常最好检查对象的功能(例如,是否可以向其添加整数)而不是其类型。

【讨论】:

  • 是的,但如果我有一个确切的定义,我可以编写函数 ;-) 我编辑了更多信息。
【解决方案5】:

isinstance(numpy.int32(4), numbers.Number) 返回False,所以这不太行。 operator.isNumberType() 确实适用于所有 numpy 数字的变体,但是,包括 numpy.array([1])

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多