【问题标题】:How do I check that a python value is an instance of a numpy dtype?如何检查 python 值是否是 numpy dtype 的实例?
【发布时间】:2017-11-14 06:04:04
【问题描述】:

如何检查给定值是否可以存储在 numpy 数组中?

例如:

import numpy as np
np.array(["a","b"])
==> array(['a', 'b'], dtype='|S1')
np.array(["a","b"]) == 1
> __main__:1: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
==> False
np.array(["a","b"]) == "a"
==> array([ True, False], dtype=bool)

我想要一个函数np_isinstance 可以做到这一点:

np_isinstance("a", np.array(["a","b"]).dtype)
==> True
np_isinstance(1, np.array(["a","b"]).dtype)
==> False
np_isinstance("a", np.array([1,2,3]).dtype)
==> False
np_isinstance(1, np.array([1,2,3]).dtype)
==> True

到目前为止,我设法想出了

def np_isinstance(o,dt):
    return np.issubdtype(np.array([o]).dtype, dt)

但这似乎是错误的,因为它在每次调用时分配一个array

人们可能希望numpy.can_cast(from, totype) 能完成这项工作,但是,唉,

np.can_cast("a",np.dtype("O"))
> TypeError: did not understand one of the types; 'None' not accepted

【问题讨论】:

  • 每次分配一个数组并不是什么大问题。它可能比您想象的要便宜(或者更确切地说,其他一切都可能比您想象的要贵,因此相对而言分配便宜)。

标签: python python-2.7 numpy isinstance


【解决方案1】:

我不知道怎么直接判断,dtype in numpy这么多,你可以用下面的函数来判断:

def np_isinstance(value, np_data):
    """
    This function for 1D np_data
    """
    flag = False
    try:
        tmp = np_data[0] + value
        flag = True
    except:
        pass
    return flag

【讨论】:

  • 如果数组np_data 为空怎么办?如果我没有数组,只有 dtype 怎么办?这比我的版本好多少?
  • 是的,你是对的。我错过了这些,我会继续思考另一种方式。
  • @sds,但是对于您的答案,请检查 o = 1.1、“dt=np.int64”、“np_isinstance(o,dt)”,您是否期望浮点数不应该插入到 np.int64 数组或 int64 数字不应该插入到浮点数组?
【解决方案2】:

当我正确理解时,整个 numpy 数组始终属于某种类型,并且数组中不能有混合项,我建议这样做:

isinstance(my_array, np.ndarray)`

这就是我在单元测试中所做的:

assert isinstance(groups, np.ndarray)

在我的生产代码中我这样做

groups = [-1, -1, 0, 2]
groups = np.asarray(g, dtype=np.uint8)

编辑:起初我误解了这个问题。您想检查是否可以在数组中插入一个角蛋白变量。那么让我们试试这个:

def is_var_allowed(x):
    try:
        x = np.uint8(x)
        return True
    except ValueError:
        return False

def main():
    my_arr = np.ones((5,), dtype=np.uint8))
    x = 7
    if is_var_allowed(x):
       my_arr.put(3, x)

这将产生一个数组[1 1 1 7 1]。可以通过给函数is_var_allowed 也提供一个 dtype 作为参数来概括这一点:

def is_var_allowed(x, func):
    try:
        x = func(x)
        return True
    except ValueError:
        return False

def main():
    my_uint_arr = np.ones((5,), dtype=np.uint8))
    x = 7
    if is_var_allowed(x, np.uint8):
       my_uint8_arr.put(3, x)

    my_char_arr = np.char.array((5,1))
    y = "Hallo"
    if is_var_allowed(y, np.char)
        my_char_arr[:] = y

【讨论】:

  • 哦,我想我误解了你的问题。您尝试检查是否可以将值放入数组中。那么为什么不尝试从中创建另一个变量:np.uint8(my_var)。你可以用 try/except 来保护它,看看它是否失败。如果没有,您可以将其放入数组中。呈现字符串时 np.uint8() 将失败
  • 还是不行。您正在假设数字 dtype。
  • 当使用一个函数作为第二个参数时,你可以泛化它
  • 我在哪里可以得到funcis_var_allowed
  • 我有一个dtype 对象。我如何将它“概括”到您的功能?最重要的是,你的版本比我的好在哪里?
【解决方案3】:

can_cast 复制您的测试用例:

In [213]: np.can_cast(type("a"), np.array(["a","b"]).dtype)
Out[213]: True
In [214]: np.can_cast(type(1), np.array(["a","b"]).dtype)
Out[214]: False
In [215]: np.can_cast(type("a"), np.array([1,2,3]).dtype)
Out[215]: False
In [217]: np.can_cast(type(1), np.array([1,2,3]).dtype)
Out[217]: True
In [219]: np.can_cast(type(1), np.dtype("O"))
Out[219]: True
In [220]: np.can_cast(type("a"), np.dtype("O"))
Out[220]: True

请注意,我将typedtype 匹配。

【讨论】:

    猜你喜欢
    • 2014-04-23
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-26
    • 1970-01-01
    相关资源
    最近更新 更多