python - 创建一个 Numpy 结构标量而不是数组

标签 python numpy

我刚刚发现了 Numpy 结构化数组,我发现它们非常强大。我脑海中自然而然地出现了一个问题:我究竟该如何创建一个 Numpy 结构标量。让我告诉你我的意思。假设我想要一个包含一些数据的结构:

import numpy as np
dtype = np.dtype([('a', np.float_), ('b', np.int_)])
ar = np.array((0.5, 1), dtype=dtype)
ar['a']

这给了我 array(0.5) 而不是 0.5。另一方面,如果我这样做:

import numpy as np
dtype = np.dtype([('a', np.float_), ('b', np.int_)])
ar = np.array([(0.5, 1)], dtype=dtype)
ar[0]['a']

我得到 0.5,就像我想要的那样。这意味着 ar[0] 不是数组,而是标量。是否有可能以比我描述的方式更优雅的方式创建结构化标量?

最佳答案

单例这个词不太合适,但我能满足您的需求。

arr = np.array((0.5, 1), dtype=dtype)

创建此 dtype 的 0d 单元素数组。检查它的数据类型和形状。

arr.item() 返回元组 (0.5, 1)。 Aso 测试 arr[()]arr.tolist()

np.float64(0.5) 使用 numpy 包装器创建一个 float 。它类似于np.array(0.5),但完全相同。他们的方法有些不同。

我对复合数据类型一无所知。


In [123]: dt = np.dtype('i,f,U10')
In [124]: dt
Out[124]: dtype([('f0', '<i4'), ('f1', '<f4'), ('f2', '<U10')])
In [125]: arr = np.array((1,2,3),dtype=dt)
In [126]: arr
Out[126]: 
array((1,  2., '3'),
      dtype=[('f0', '<i4'), ('f1', '<f4'), ('f2', '<U10')])
In [127]: arr.shape
Out[127]: ()

arr 是一个 0d 1 元素数组。它可以被索引:

In [128]: arr[()]
Out[128]: (1,  2., '3')
In [129]: type(_)
Out[129]: numpy.void

此索引生成一个 np.void 对象。在 0d float 组上做同样的事情会产生一个 np.float 对象。

但是你不能使用np.void((1,2,3), dtype=dt)直接创建这样一个对象(对比np.float(12.34 )).

item 是从数组中提取“标量”的常规方法。这里它返回一个元组,与我们用作创建 arr 的输入的对象类型相同:

In [131]: arr.item()
Out[131]: (1, 2.0, '3')
In [132]: type(_)
Out[132]: tuple

np.asscalar(arr) 返回相同的元组。

np.void 对象和元组之间的一个区别是,它仍然可以用字段名索引,arr[()]['f0'],而元组必须通过数字 arr.item()[0] 进行索引。 void 仍然有一个 dtype,而元组没有。

fromrecords 生成一个recarray。这类似于结构化数组,但允许我们将字段作为属性访问。它实际上可能是一个较旧的类,已合并到 numpy 中,因此有 np.rec 前缀。大多数情况下,我们使用结构化数组,尽管 np.rec 仍然有一些方便的功能。 (实际上在 numpy.lib.recfunctions 中):

In [133]: res = np.rec.fromrecords((1,2,3), dt)
In [134]: res
Out[134]: 
rec.array((1,  2., '3'), 
          dtype=[('f0', '<i4'), ('f1', '<f4'), ('f2', '<U10')])
In [135]: res.f0
Out[135]: array(1, dtype=int32)
In [136]: res.item()
Out[136]: (1, 2.0, '3')
In [137]: type(_)
Out[137]: tuple
In [138]: res[()]
Out[138]: (1, 2.0, '3')
In [139]: type(_)
Out[139]: numpy.record

所以这产生了一个 np.record 而不是 np.void。但这只是一个子类:

In [143]: numpy.record.__mro__
Out[143]: (numpy.record, numpy.void, numpy.flexible, numpy.generic, object)

按字段名访问结构化数组会得到相应数据类型(和相同形状)的数组

In [145]: arr['f1']
Out[145]: array(2.0, dtype=float32)
In [146]: arr[()]['f1']
Out[146]: 2.0
In [147]: type(_)
Out[147]: numpy.float32

Out[146] 也可以用 np.float32(2.0) 创建。


检查我对一维数组的 ar[0] 的评论:

In [158]: arr1d = np.array([(1,2,3)], dt)
In [159]: arr1d
Out[159]: 
array([(1,  2., '3')],
      dtype=[('f0', '<i4'), ('f1', '<f4'), ('f2', '<U10')])
In [160]: arr1d[0]
Out[160]: (1,  2., '3')
In [161]: type(_)
Out[161]: numpy.void

所以 arr[()]arr1d[0] 对它们各自大小的数组做同样的事情。同样arr2d[0,0],也可以写成arr2d[(0,0)]

关于python - 创建一个 Numpy 结构标量而不是数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47755723/

相关文章:

python - DJango 包含不适用于 JSONField

python - 用于算术运算的 BFS

javascript - django 动态过滤表单

python - 获取每行列表中最常用的单词

python - 如何有效地使用索引数组作为掩码将 numpy 数组转换为 bool 数组?

python - 通过 Macports 安装 matplotlib basemap 后, basemap 的示例 python 代码未运行

python - 是否可以使用 reduce 对列表进行排序?

python - NumPy 中的 arctan2 差异

python - 使用具有大量维度的 numpy.array

python - Numpy 子类属性切片