-1

I have a NumPy array as follows:

[[[  0   0]]

 [[  0 479]]

 [[639 479]]

 [[639   0]]]

and I would like to convert it into something like so:

[(  0   0)

 (  0 479)

 (639 479)

 (639   0), dtype=dtype([('x', '<i2'), ('y', '<i2')])]

I have tried to use the following function:

def flat(contour):
        for point in contour:
            yield tuple(point[0])

like so:

contour=np.fromiter(flat(contour),Point)

but this gives me the following error: ValueError: setting an array element with a sequence. so how can I turn certain "dimensions" of a NumPy array into NumPy "objects" (or whatever else they are called in NumPy)

0

1 Answer 1

1
In [117]: arr = np.array([[[0,0]],[[0,479]],[[639,479]],[[639,0]]])                                  
In [118]: arr                                                                                        
Out[118]: 
array([[[  0,   0]],

       [[  0, 479]],

       [[639, 479]],

       [[639,   0]]])
In [119]: arr.shape                                                                                  
Out[119]: (4, 1, 2)

You apparently want a structured array, https://numpy.org/devdocs/user/basics.rec.html#

There's a handy tool for converting a numeric array to a structured one:

In [120]: import numpy.lib.recfunctions as rf                                                        
In [121]: rf.unstructured_to_structured(arr,names=['x','y'])                                         
Out[121]: 
array([[(  0,   0)],
       [(  0, 479)],
       [(639, 479)],
       [(639,   0)]], dtype=[('x', '<i8'), ('y', '<i8')])
In [122]: _.shape                                                                                    
Out[122]: (4, 1)

or using your desired dtype:

In [126]: rf.unstructured_to_structured(arr,dtype=np.dtype([('x', '<i2'), ('y', '<i2')]))            
Out[126]: 
array([[(  0,   0)],
       [(  0, 479)],
       [(639, 479)],
       [(639,   0)]], dtype=[('x', '<i2'), ('y', '<i2')])

or create a 'blank' array with the desired dtype and shape, and assign fields:

In [127]: res = np.zeros((4,1), dtype=np.dtype([('x', '<i2'), ('y', '<i2')]))                        
In [128]: res                                                                                        
Out[128]: 
array([[(0, 0)],
       [(0, 0)],
       [(0, 0)],
       [(0, 0)]], dtype=[('x', '<i2'), ('y', '<i2')])
In [129]: res['x'] = arr[:,:,0]                                                                      
In [130]: res['y'] = arr[:,:,1]                                                                      
In [131]: res                                                                                        
Out[131]: 
array([[(  0,   0)],
       [(  0, 479)],
       [(639, 479)],
       [(639,   0)]], dtype=[('x', '<i2'), ('y', '<i2')])

Or from a list of tuples (list of lists of tuples in your case):

In [132]: arr.tolist()                                                                               
Out[132]: [[[0, 0]], [[0, 479]], [[639, 479]], [[639, 0]]]

In [134]: [[tuple(i) for i in x] for x in arr.tolist()]                                              
Out[134]: [[(0, 0)], [(0, 479)], [(639, 479)], [(639, 0)]]

In [135]: np.array([[tuple(i) for i in x] for x in arr.tolist()], dtype=[('x', '<i2'), ('y', '<i2')])
     ...:                                                                                            
Out[135]: 
array([[(  0,   0)],
       [(  0, 479)],
       [(639, 479)],
       [(639,   0)]], dtype=[('x', '<i2'), ('y', '<i2')])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.