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