【问题标题】:check type within numpy array检查numpy数组中的类型
【发布时间】:2016-10-28 19:29:39
【问题描述】:

我有不同类型的数据。其中大多数是int,有时是floatint 的大小不同,因此大小为 8/ 16/ 32 位。
对于这种情况,我正在创建一个数字类型转换器。因此我使用isinstence() 检查类型。这是因为我读到isinstance()type() 差。

关键是我得到的很多数据都是 numpy 数组。我使用 spyder 作为 IDE,然后我看到变量也是一种类型。但是当我输入isinstance(var,'type i read') 时,我得到False

我做了一些检查:

a = 2.17 
b = 3 
c = np.array(np.random.rand(2, 8))
d = np.array([1])

在那里isinstance(var,type) 我明白了:

isinstance(a, float)
True
isinstance(b, int)
True
isinstance(c, float)  # or isinstance(c, np.float64)
False
isinstance(d, int)  # or isinstance(c, np.int32)
False

cd 在我询问时为真

isinstance(c, np.ndarray)
True
isinstance(d, np.ndarray)
True

我可以通过ndarray 中的步骤检查

isinstance(c[i][j], np.float64)
True
isinstance(d[i], np.int32)
True

但这意味着对于每个维度我都必须添加一个新索引,否则它又是False。 我可以用dtype 来检查那里的类型,比如c.dtype == 'float64'...

好吧,我发现并尝试过... 我的问题基本上是:

  • var.dtype 方法与isinstance()type() 相比如何(最差/更好等)?
  • 如果var.dtypeisinstance() 更糟,isinstance() 中是否有一些方法没有所有手动索引? (自动索引等)?

【问题讨论】:

  • 你在哪里有不同整数大小的数据?作为 Python 对象、numpy 数组、文件?您可能需要为使用数值类型转换器提供更多上下文。
  • 主要是多声道音频文件
  • 你打算如何转换数据类型?
  • 从 int 类型/numpy.intXX 类型更改为 (numpy.)float(64) 并按整数大小缩小。所以一切都是 -1 min 到 +1 max
  • 我在np.can_cast.astype 的回答中添加了注释。

标签: python-3.x numpy isinstance


【解决方案1】:

数组是np.ndarray 类型的对象。它的值或元素存储在数据缓冲区中,可以将其视为连续的内存字节块。数据缓冲区中的字节没有类型,因为它们不是 Python 对象。

该数组有一个dtype 参数,用于解释这些字节。如果dtypeint32(有各种同义词),4 个字节被解释为一个整数。访问一个元素,比如c[0] 会给出一个取决于 dtype 的新对象,例如对象类型np.int32

c[0].item 会给出对应类型的 Python 对象:

In [2102]: c=np.array([1])
In [2103]: c.dtype
Out[2103]: dtype('int32')
In [2104]: type(c)
Out[2104]: numpy.ndarray
In [2105]: type(c[0])
Out[2105]: numpy.int32
In [2107]: c[0].item()
Out[2107]: 1
In [2108]: type(c[0].item())
Out[2108]: int

(并且c[0].dtypec.dtype 相同;您无需索引数组的各个元素来检查它们的数据类型)。

这个数组的同样4个字节可以看成dtypeint8——一个单字节整数。

In [2112]: c.view('b')
Out[2112]: array([1, 0, 0, 0], dtype=int8)

这个替代视图的单个元素是np.int8,但是当我使用item() 时,我得到一个Python 整数。没有int8 Python 数字类型。

In [2113]: type(c.view('b')[0])
Out[2113]: numpy.int8
In [2115]: type(c.view('b')[0].item())
Out[2115]: int

列表包含指向 Python 对象的指针,每个对象都有一个类型。 dtype=object 的数组也是如此。但常见的数值数组不包含 Python 整数或浮点数。它有一个数据缓冲区,可以根据dtype 以各种方式进行解释。 Python 整数的大小没有不同,至少与 numpy dtype 的大小不同。

所以isinstancetype() 的内容不适用于ndarray 的内容。

=====================

从我收集的 cmets 中,您正在尝试将整数数组转换为浮点数。您没有转换标量。如果是这样,那么dtype 才是最重要的;数组总是有一个dtype。目前尚不清楚您是否可以将np.float32 转换为np.float64

我建议研究和试验np.can_cast 函数和x.astype 方法。

x.astype(np.float64, copy=False)

例如会将所有 int dtypes 转换为 float,而不复制已经是 float64 的那些。它可以复制和转换np.float32 个。

还要查看这些函数的casting 参数。

============================

我在scipy.optimize.minimize找到了另一个测试工具

In [156]: np.typecodes
Out[156]: 
{'All': '?bhilqpBHILQPefdgFDGSUVOMm',
 'AllFloat': 'efdgFDG',
 'AllInteger': 'bBhHiIlLqQpP',
 'Character': 'c',
 'Complex': 'FDG',
 'Datetime': 'Mm',
 'Float': 'efdg',
 'Integer': 'bhilqp',
 'UnsignedInteger': 'BHILQP'}

它可以用来检查整数:

if x0.dtype.kind in np.typecodes["AllInteger"]:
    x0 = np.asarray(x0, dtype=float)

【讨论】:

    【解决方案2】:

    要直接回答问题,您可以这样做:

    isinstance(arr.flat[0], np.floating)

    • .flat 将向下折叠任意数量的维度,因此您可以轻松访问第 0 个元素。
    • np.floating 将匹配任何 numpy 浮点类型

    【讨论】:

    • 这假定数组第一个元素。它可能不会 - 数组可以有 0 个元素。这完全不如 dtype 检查。
    【解决方案3】:

    numpy 数组中的所有条目都属于同一类型。 numpy 类型和 Python 类型不是一回事。这可能有点令人困惑,但 numpy 所指的类型更像是 C 等语言使用的类型 - 你可能会说更接近机器的低级。

    你不能说哪种更好,因为这就像比较苹果和橘子。

    【讨论】:

    • 你应该说all entries ... are of the same dtypenumpy dtype。数组的类型是ndarray,不管它的dtype
    【解决方案4】:

    与@rasen58 和@hpaulj 略有不同:

    要检查 np 数组 c 是否具有浮点类型的元素,c.dtype == np.floating 适合我。

    【讨论】:

    • FWIW,当我尝试这个时,我得到了/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:79: DeprecationWarning: Converting 'np.inexact' or 'np.floating' to a dtype is deprecated. The current result is 'float64' which is not strictly correct.
    • 但是使用c.dtype == np.double 确实对我有用。更多关于 numpy 类型名称的信息:numpy.org/doc/stable/user/basics.types.html
    • 对我来说,当我测试c.dtype == float 而不是c.dtype == np.floating 时,@CraigReynolds 描述的警告消失了我不太确定这些测试的等效性,但就我而言,我得到了预期的结果。
    • 感谢@Malo Pocheau。那时我还很年轻很天真,大约 4 个月前,刚接触 Python、numpy、深度学习......
    【解决方案5】:

    我写了一个小包装器,它的工作原理基本上类似于isinstance,并接受一个对象o 和一个类(或类元组)c。 唯一的区别是如果isinstance(o, np.ndarray)Trueo.flat[0] 会根据映射的 numpy 数据类型进行检查(请参阅字典 c2np) 我主要与boolintfloatstr 合作,但这个列表可以更改/扩展。 请注意np.integernp.floating 是大多数/全部的集合?可用的 numpy 子类型为 np.int8、np.unit16、...

    def np_isinstance(o, c):
        c2np = {bool: np.bool, int: np.integer, float: np.floating, str: np.str}
    
        if isinstance(o, np.ndarray):
            c = (c2np[cc] for cc in c) if isinstance(c, tuple) else c2np[c]
            return isinstance(o.flat[0], c)
    
        else:
            return isinstance(o, c)
    

    一些例子:

    # Like isinstance if o is not np.ndarray
    np_isinstance(('this', 'that'), tuple)  # True
    np_isinstance(4.4, int)                 # False
    np_isinstance(4.4, float)               # True
    
    #
    np_isinstance(np.ones(4, dtype=int), int)    # True
    np_isinstance(np.ones(4, dtype=int), float)  # False
    np_isinstance(np.full((4, 4), 'bert'), str)  # True
    

    【讨论】:

    • 这对于 bool 来说失败,并且严格不如 dtype 检查。
    猜你喜欢
    • 2020-07-02
    • 2012-06-03
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2012-03-17
    • 2021-08-07
    • 1970-01-01
    相关资源
    最近更新 更多