Convert 3d numpy array into a 2d numpy array (where contents are tuples)

Here is a one-liner which takes a few seconds on the full (6602, 3176, 2) problem

a = np.random.rand(6602, 3176, 2)

b = a.view([(f'f{i}',a.dtype) for i in range(a.shape[-1])])[...,0].astype('O')

The trick here is to viewcast to a compund dtype which spans exactly one row. When such a compound dtype is then cast on to object each compound element is converted to a tuple.

UPDATE (hat tip @hpaulj) there is a library function that does precisely the view casting we do manually: numpy.lib.recfunctions.unstructured_to_structured

Using this we can write a more readable version of the above:

import numpy.lib.recfunctions as nlr

b = nlr.unstructured_to_structured(a).astype('O')

If you really want to do, what you want to do, you have to set dtype of you array to object. E.g., if you have the mentioned array:

a = np.random.rand(6602, 3176, 2)

You could create a second empty array with shape (6602, 3176) and set dtype to object:

b = np.empty(a[:,:,0].shape, dtype=object)

and fill your array with tuples.

But in the end there is no big advantage! I'd just use slicing to get the tuples from your initial array a. You can just access the tuples of indexes n (1st dimension) and m (2nd dimension) and forget about the third dimension and slice your 3d array:

a[n,m,:]

Tags:

Python

Numpy