29

我有不同类型的数据。他们中的大多数是int有时float。大小不同,因此int大小为 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

c当我问的d时候是真的

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.dtype更糟糕?(自动索引等)?isinstance()isinstance()
4

5 回答 5

36

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

该数组有一个dtype参数,用于解释这些字节。如果dtypeint32(有各种同义词),4 个字节被解释为一个整数。访问一个元素,比如说c[0]给出一个依赖于 dtype 的新对象,例如 object type 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].dtype与 for 相同c.dtype;您不需要索引数组的各个元素来检查它们的 dtype)。

该数组的相同 4 个字节可以被视为dtype int8- 一个单字节整数。

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

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

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 dtypes 的大小不同。

所以isinstanceand的type()东西不适用于ndarray.

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

从我收集的评论中,您正在尝试将整数数组转换为浮点数。您没有转换标量。如果是这样,那dtype才是最重要的;数组总是有一个dtype. 目前尚不清楚您是否可以将 a 投射np.float32np.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)
于 2016-10-28T20:41:41.257 回答
8

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

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

  • .flat将向下折叠任意数量的维度,因此您可以轻松访问第 0 个元素。
  • np.floating将匹配任何 numpy 浮点类型
于 2019-06-11T23:22:43.767 回答
4

与@rasen58 和@hpaulj 略有不同:

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

于 2021-04-07T23:08:20.937 回答
1

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

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

于 2016-10-28T19:42:48.433 回答
-1

我写了一个小包装器,它的工作原理基本上类似于isinstance并接受一个对象o和一个类(或类元组)c。唯一的区别是 if isinstance(o, np.ndarray)is True,o.flat[0]是针对映射的 numpy 数据类型(请参阅 dict c2np)进行检查的,我主要使用bool, int, floatstr但是可以更改/扩展此列表。请注意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
于 2020-09-28T15:54:39.930 回答