Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
189 views
in Technique[技术] by (71.8m points)

python - How to turn a numpy array to a numpy object?

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)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
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')])

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...