代码之家  ›  专栏  ›  技术社区  ›  j-dr

重新排列视图为Ndaray

  •  0
  • j-dr  · 技术社区  · 6 年前

    在以前版本的numpy中,我可以做如下操作:

    data = np.array([(0,1,2),(3,4,5),(6,7,8)], dtype=np.dtype([('a','<f8'), ('b','<f8'),('c','<f8')]))
    
    
    data_nd = data[['a','b']].view(('<f8',2))
    

    这将给我一个原始重新排列的视图 data 作为类型的二维数组 np.float32 .

    在numpy版本1.14中,当我尝试上面的第二行时,我得到了错误:

    ValueError: Changing the dtype to a subarray type is only supported if the total itemsize is unchanged
    

    这是因为 data[['a','b']] 还是24岁。好的,那很好,但是是否有某种方法可以获取更新itemsize的数据列的副本,以便生成所需的视图?

    例如,甚至制作 数据[['a','b']] 仍然会导致itemsize为24,这我不理解。

    1 回复  |  直到 6 年前
        1
  •  0
  •   hpaulj    6 年前

    您是否意识到,如果没有元组,您的重数组是3x3,具有复制的字段值:

    In [46]: data
    Out[46]: 
    array([[(0., 0., 0.), (1., 1., 1.), (2., 2., 2.)],
           [(3., 3., 3.), (4., 4., 4.), (5., 5., 5.)],
           [(6., 6., 6.), (7., 7., 7.), (8., 8., 8.)]],
          dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<f8')])
    

    无论如何,整个阵列的视图仍然有效,您可以对其使用传统的列切片:

    In [47]: data.view(('float',(3,)))
    Out[47]: 
    array([[[0., 0., 0.],
            [1., 1., 1.],
            [2., 2., 2.]],
    
           [[3., 3., 3.],
            [4., 4., 4.],
            [5., 5., 5.]],
    
           [[6., 6., 6.],
            [7., 7., 7.],
            [8., 8., 8.]]])
    In [48]: _.shape
    Out[48]: (3, 3, 3)
    

    tolist 是用于与结构化阵列进行转换的旧备用阵列。它仍然有效:

    In [49]: np.array(data[['a','b']].tolist())
    Out[49]: 
    array([[[0., 0.],
            [1., 1.],
            [2., 2.]],
    
           [[3., 3.],
            [4., 4.],
            [5., 5.]],
    
           [[6., 6.],
            [7., 7.],
            [8., 8.]]])
    

    更改 data 创建包含元组实际上并不会改变视图行为,但可能更接近您想要的(或我想要的):

    In [50]: data1 = np.array([(0,1,2),(3,4,5),(6,7,8)], dtype=np.dtype([('a','<f8')
        ...: , ('b','<f8'),('c','<f8')]))
    In [51]: data1
    Out[51]: 
    array([(0., 1., 2.), (3., 4., 5.), (6., 7., 8.)],
          dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<f8')])
    

    请注意,子字段显示现在包括偏移参数。

    In [53]: data1[['a','b']]
    Out[53]: 
    array([(0., 1.), (3., 4.), (6., 7.)],
          dtype={'names':['a','b'], 'formats':['<f8','<f8'], 'offsets':[0,8], 'itemsize':24})
    

    基础数据库是相同的,因此3列视图可以使用和不使用子字段索引:

    In [54]: data1[['a','b']].view((float,(3,)))
    Out[54]: 
    array([[0., 1., 2.],
           [3., 4., 5.],
           [6., 7., 8.]])
    In [55]: data1.view((float,(3,)))
    Out[55]: 
    array([[0., 1., 2.],
           [3., 4., 5.],
           [6., 7., 8.]])
    

    我还没有读到最新的变化。相反,我使用了过去行之有效的各种技巧。从结构化数组转换到结构化数组从来都不是简单而简单的。