代码之家  ›  专栏  ›  技术社区  ›  Hameer Abbasi

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

  •  6
  • Hameer Abbasi  · 技术社区  · 8 年前

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

    2 回复  |  直到 8 年前
        1
  •  5
  •   hpaulj    8 年前

    单身这个词不太合适,但我能得到你想要的。

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

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

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

    np.float64(0.5) 使用numpy包装创建浮点。与相似,但完全相同 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浮点数组上执行相同的操作将生成 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。无效的 对象和元组仍然可以使用字段名对其进行索引, 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。无效的 . 但这只是一个子类:

    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] 对于1d阵列:

    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)] .

        2
  •  4
  •   Georgy rassa45    8 年前

    使用 np.asscalar .
    在你的两种情况下 np.asscalar(ar['a']) .

    此外,您可能会发现 np.item .