How do I unpack a numpy array of tuples into an ndarray?

后端 未结 2 1667
不思量自难忘°
不思量自难忘° 2021-01-22 03:02

I have a 2D numpy array with elements of the type np.void that are essentially tuples. Is there an efficient way to unpack the values in these tuples to a 3rd dime

相关标签:
2条回答
  • 2021-01-22 03:21
    In [601]: a = np.array([[(1, 2,  3), (1, 2,  3), (1, 2, 3)], 
         ...:        [(1, 2,  3), (1, 2, 3), (1, 2, 3)], 
         ...:        [(1, 2, 3), (1, 2, 3), (1, 2, 3)]], 
         ...:       dtype=[('B4', '<u2'), ('B3', '<u2'), ('B2', '<u2')])                 
    In [602]: a.dtype                                                                    
    Out[602]: dtype([('B4', '<u2'), ('B3', '<u2'), ('B2', '<u2')])
    In [603]: a.shape                                                                    
    Out[603]: (3, 3)
    

    This is a structured array, with a compound dtype. The tuples display individual elements of the 2d array.

    Recent numpy versions have added a function to conveniently convert structured arrays to unstructured:

    In [606]: b=rf.structured_to_unstructured(a)                                         
    In [607]: b                                                                          
    Out[607]: 
    array([[[1, 2, 3],
            [1, 2, 3],
            [1, 2, 3]],
    
           [[1, 2, 3],
            [1, 2, 3],
            [1, 2, 3]],
    
           [[1, 2, 3],
            [1, 2, 3],
            [1, 2, 3]]], dtype=uint16)
    In [608]: b[:,:,1]                                                                   
    Out[608]: 
    array([[2, 2, 2],
           [2, 2, 2],
           [2, 2, 2]], dtype=uint16)
    

    a has 3 fields. Individual fields can be accessed by name:

    In [610]: a['B4']                                                                    
    Out[610]: 
    array([[1, 1, 1],
           [1, 1, 1],
           [1, 1, 1]], dtype=uint16)
    

    That means you could construct the 3d array by concatenating the 3 individual fields:

    np.stack([a['B4'],a['B3'],a['B2']]) 
    

    This is like your last solution, but without the i,j iteration.


    The view approach in the other answer works in this case because all fields have the same dtype, <u2. That means the same underlying data can be viewed as individual <u2 elements, or a groups of 3 of these.

    import numpy.lib.recfunctions as rf
    

    The rf.structured_to_unstructured works in more general cases where view does not, such as a mix of dtypes, (e.g. floats and integers).

    0 讨论(0)
  • 2021-01-22 03:36

    You can view as a standard numpy array to allow for the indexing you're after.

    b = a.view('(3,)<u2')
    

    array([[[1, 2, 3],
            [1, 2, 3],
            [1, 2, 3]],
    
           [[1, 2, 3],
            [1, 2, 3],
            [1, 2, 3]],
    
           [[1, 2, 3],
            [1, 2, 3],
            [1, 2, 3]]], dtype=uint16)
    

    >>> b.shape
    (3, 3, 3)
    >>> b[:, :, 0]
    array([[1, 1, 1],
           [1, 1, 1],
           [1, 1, 1]], dtype=uint16)
    
    0 讨论(0)
提交回复
热议问题