创建Numpy结构标量而不是数组

dba5bblo  于 2023-05-17  发布在  其他
关注(0)|答案(2)|浏览(83)

我刚刚发现了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]不是数组,而是标量。有没有可能用一种比我描述的更优雅的方式来创建一个结构化的标量?

1wnzp6jl

1wnzp6jl1#

“单身”这个词不太合适,但我明白你的意思。

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

创建此数据类型的第0d个单元素数组。检查其dtype和形状。
arr.item()返回元组(0.5, 1)。阿索测试arr[()]arr.tolist()
np.float64(0.5)使用numpy Package 器创建一个float。它类似于np.array(0.5),但不完全相同。他们的方法有些不同。
我不知道任何类似于复合dtype的东西。

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浮点数组执行相同的操作将生成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)

通过字段名访问结构化数组会得到一个具有相应dtype(和相同形状)的数组

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)创建。
检查我对1d数组的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)]

pxy2qtax

pxy2qtax2#

使用np.asscalar
在这两种情况下,它都只是np.asscalar(ar['a'])
另外,您可能会发现有用的np.item

相关问题