How to change the dtype of a numpy array to 'object'?

19,618

Let's make sure we understand what you are starting with:

In [7]: weights
Out[7]: 
[array([[-2.66665269,  0.        ],
        [-0.36358187,  0.        ],
        [ 1.55058871,  0.        ],
        [ 3.91364328,  0.        ]]), array([[ 0.],
        [ 0.]])]
In [8]: len(weights)
Out[8]: 2
In [9]: weights[0]
Out[9]: 
array([[-2.66665269,  0.        ],
       [-0.36358187,  0.        ],
       [ 1.55058871,  0.        ],
       [ 3.91364328,  0.        ]])
In [10]: weights[0].dtype
Out[10]: dtype('float64')
In [11]: weights[0].shape
Out[11]: (4, 2)

In [13]: weights[1]
Out[13]: 
array([[ 0.],
       [ 0.]])
In [14]: weights[1].dtype
Out[14]: dtype('float64')
In [15]: weights[1].shape
Out[15]: (2, 1)

This is a 2 item list, containing two arrays. Both are 2d float.

First you wrap the whole list in an object array:

In [16]: duh =np.array(weights,dtype='object')
In [17]: duh
Out[17]: 
array([ array([[-2.66665269,  0.        ],
       [-0.36358187,  0.        ],
       [ 1.55058871,  0.        ],
       [ 3.91364328,  0.        ]]),
       array([[ 0.],
       [ 0.]])], dtype=object)

This is a 2 element array, shape (2,). But it doesn't change the nature of the elements. And there's a potential gotcha - if the element arrays had the same shape, it would have created a 3d array of objects.

This is not the right syntax for change the dtype of an array. dtype is not a writable property/attribute.

weights[1].dtype='object'

We can use astype instead:

In [19]: weights[1].astype(object)
Out[19]: 
array([[0.0],
       [0.0]], dtype=object)
In [20]: weights[1]=weights[1].astype(object)
In [21]: weights
Out[21]: 
[array([[-2.66665269,  0.        ],
        [-0.36358187,  0.        ],
        [ 1.55058871,  0.        ],
        [ 3.91364328,  0.        ]]), array([[0.0],
        [0.0]], dtype=object)]

It makes a new array, which we'd have write back into the original list.

Now I can change an element of that 2nd array

In [22]: weights[1][0,0]=None
In [23]: weights
Out[23]: 
[array([[-2.66665269,  0.        ],
        [-0.36358187,  0.        ],
        [ 1.55058871,  0.        ],
        [ 3.91364328,  0.        ]]), array([[None],
        [0.0]], dtype=object)]

When playing games like this you have to pay attention to where you have arrays and where they are lists. And pay attention to the shape and dtype of the arrays. Don't blindly index and hope for the best. Display/print these attributes, or the whole array if it isn't too large.

Share:
19,618
Perm. Questiin
Author by

Perm. Questiin

Updated on June 05, 2022

Comments

  • Perm. Questiin
    Perm. Questiin about 2 years

    My goal is to do this:

    weights[1][0][0] = some_object(1)
    

    But it throws this error:

    TypeError: float() argument must be a string or a number, not 'some_object'
    

    Because of this I wawnt to change the dtype to 'object' In my code I have weights. They look like this:

    >>> print(weights)
    [ array([[-2.66665269,  0.        ],
       [-0.36358187,  0.        ],
       [ 1.55058871,  0.        ],
       [ 3.91364328,  0.        ]])
      array([[ 0.],
       [ 0.]])]
    

    I want to change weights[1][0][0] to an object. I am refering to the 0 in:

    [ array([[-2.66665269,  0.        ],
       [-0.36358187,  0.        ],
       [ 1.55058871,  0.        ],
       [ 3.91364328,  0.        ]])
      array([[ 0.],                        #this zero right here
       [ 0.]])]
    

    I want to convert that 0 to some_object(1). So I change the dtype to 'object', but it remains float!

    >>> weights=np.array(weights,dtype='object')
    >>> weights.dtype
    object
    >>> weights[1].dtype
    float64
    >>> weights[1][0].dtype
    float64
    >>> weights[1][0][0].dtype
    float64
    

    So now I try:

    >>> weights[1].dtype='object'
    TypeError: Cannot change data-type for object array.
    

    and this

    >>> weights[1][0].dtype='object'
    TypeError: Cannot change data-type for object array.
    

    so now I cannot do this:

    weights[1][0][0] = some_object(1)
    TypeError: float() argument must be a string or a number, not 'object'
    

    because the dtype is incorrect. How do I change the dtype?

    Edit: I found an answer.

    weights[1] = weights[1].tolist()
    weights[1][0][0] = some_object(1)
    ....
    weights=np.array(weights)