Reputation: 429
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)
Upvotes: 3
Views: 35135
Reputation: 231335
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.
Upvotes: 4