Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a Numpy 2D array with object dtype to a regular 2D array of floats

As part of broader program I am working on, I ended up with object arrays with strings, 3D coordinates and etc all mixed. I know object arrays might not be very favorite in comparison to structured arrays but I am hoping to get around this without changing a lot of codes.

Lets assume every row of my array obj_array (with N rows) has format of

Single entry/object of obj_array:  ['NAME',[10.0,20.0,30.0],....]  

Now, I am trying to load this object array and slice the 3D coordinate chunk. Up to here, everything works fine with simply asking lets say for .

obj_array[:,[1,2,3]] 

However the result is also an object array and I will face problem as I want to form a 2D array of floats with:

size [N,3] of N rows and 3 entries of X,Y,Z coordinates 

For now, I am looping over rows and assigning every row to a row of a destination 2D flot array to get around the problem. I am wondering if there is any better way with array conversion tools of numpy ? I tried a few things and could not get around it.

Centers   = np.zeros([N,3])  for row in range(obj_array.shape[0]):     Centers[row,:] = obj_array[row,1] 

Thanks

like image 581
Moe Avatar asked Oct 18 '13 21:10

Moe


People also ask

How do I change the Dtype of a NumPy array?

We have a method called astype(data_type) to change the data type of a numpy array. If we have a numpy array of type float64, then we can change it to int32 by giving the data type to the astype() method of numpy array. We can check the type of numpy array using the dtype class.

How do you transpose a 2D array in NumPy?

To transpose NumPy array ndarray (swap rows and columns), use the T attribute ( . T ), the ndarray method transpose() and the numpy. transpose() function.

How do you convert an object to an array in Python?

Using numpy.asarray() , and true (by default) in the case of np. array() . This means that np. array() will make a copy of the object (by default) and convert that to an array, while np.

How is it possible to cast an array into different data types like float?

Method 1 : Here, we can utilize the astype() function that is offered by NumPy. This function creates another copy of the initial array with the specified data type, float in this case, and we can then assign this copy to a specific identifier, which is convertedArray.


2 Answers

Nasty little problem... I have been fooling around with this toy example:

>>> arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object) >>> arr array([['one', [1, 2, 3]],        ['two', [4, 5, 6]]], dtype=object) 

My first guess was:

>>> np.array(arr[:, 1]) array([[1, 2, 3], [4, 5, 6]], dtype=object) 

But that keeps the object dtype, so perhaps then:

>>> np.array(arr[:, 1], dtype=np.float) Traceback (most recent call last):   File "<stdin>", line 1, in <module> ValueError: setting an array element with a sequence. 

You can normally work around this doing the following:

>>> np.array(arr[:, 1], dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3) Traceback (most recent call last):   File "<stdin>", line 1, in <module> TypeError: expected a readable buffer object 

Not here though, which was kind of puzzling. Apparently it is the fact that the objects in your array are lists that throws this off, as replacing the lists with tuples works:

>>> np.array([tuple(j) for j in arr[:, 1]], ...          dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3) array([[ 1.,  2.,  3.],        [ 4.,  5.,  6.]]) 

Since there doesn't seem to be any entirely satisfactory solution, the easiest is probably to go with:

>>> np.array(list(arr[:, 1]), dtype=np.float) array([[ 1.,  2.,  3.],        [ 4.,  5.,  6.]]) 

Although that will not be very efficient, probably better to go with something like:

>>> np.fromiter((tuple(j) for j in arr[:, 1]), dtype=[('', np.float)]*3, ...             count=len(arr)).view(np.float).reshape(-1, 3) array([[ 1.,  2.,  3.],        [ 4.,  5.,  6.]]) 
like image 183
Jaime Avatar answered Oct 05 '22 22:10

Jaime


Based on Jaime's toy example I think you can do this very simply using np.vstack():

arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object) float_arr = np.vstack(arr[:, 1]).astype(np.float) 

This will work regardless of whether the 'numeric' elements in your object array are 1D numpy arrays, lists or tuples.

like image 26
ali_m Avatar answered Oct 05 '22 22:10

ali_m