Arturo
Arturo

Reputation: 3779

Overwrite array size with new array size and values in python

I have the following python code that outputs:

# Somecode block before
#####################
print np.shape(data2['sac']['startx'][0][0])
print np.shape(startx_buff)
# New Completed Assignment
data2['sac']['startx'][0][0][0] = startx_buff

#**shape of data2['sac']['startx'][0][0] = (2, 119, 20)**

#**shape of startx_buff = (2,120,20)**

#***Error: data2['sac']['startx'][0][0][0] = startx_buff

ValueError: could not broadcast input array from shape (2,120,20) into shape (119,20)***

And I'd essentially like to overwrite the data2['sac']['startx'][0][0] entry to have the (2,120,20) dimensions (as well as the values of startx_buff). The reason: After post-processing I noticed an entry value was missing. In MATLAB this is no problem since it is more flexible, and I can potentially redefine a variable by assigning it a new value, and array/cell shape. But other things I've tried in python for a workaround doesnt' work is:

del data2['sac']['startx'][0][0]
data2['sac']['startx'][0][0] = np.empty((2,120,20))
#Error: won't let me delete all the values in the array

I'm not quite sure what the solution is, or even under what to look for online (I tried looking for overwriting/overloading array size). Besides finding the answer to this problem, what would be the correct terminology for this issue?

Upvotes: 0

Views: 418

Answers (2)

hpaulj
hpaulj

Reputation: 231738

With simpler names (we don't need all that dictionary indexing), what you are trying to do is:

In [212]: X = np.zeros((2,119,20),int)

In [214]: y = np.ones((2,120,20),int)
In [215]: X[0,:,:] = y
...    
ValueError: could not broadcast input array from shape (2,120,20) into shape (119,20)

MATLAB does allow some sort of automatic dimension growth, but somehow I doubt if it is this flexible. That would be dangerous. When I worked in MATLAB is never depended on that kind of action. In any case, numpy expects an exact match - within the rules of broadcasting (which adds a lot of power that MATLAB does not (or at least did not) have).

The point is that X[0,:,:] (I added the : for reader clarity) is a (119,20) slot. There's no way that a (2,120,20) block can fit there.

This does work (reducing the LHS so it fits):

X[0,:,:] = y[0, :119, :]

We could also grow X with a concatenate

In [219]: X1 = np.concatenate((X, np.zeros((2,1,20),int)), axis=1)
In [220]: X1.shape
Out[220]: (2, 120, 20)
In [221]: X1[0,:,:] = y[0,:,:]

resize also works, but concatenate gives more control over the fill value:

In [222]: np.resize(X, (2,120,20)).shape
Out[222]: (2, 120, 20)

np.empty((2,120,20)) is a full array with that shape. It's empty only in the sense that the values are unspecified. numpy does not have the equivalent of the list, x[1:3]=[] (well there is a np.delete function.)

data2['sac']['startx'][0][0] expression is a bit unclear. In Python that looks like a couple levels of dictionary access followed by a couple levels of list indexing.

Keep in mind that numpy arrays are roughly equivalent to MATLAB matrices, and python lists more like MATLAB cells. Lists like cells can hold anything, including arrays.

In [227]: alist[0]=np.arange(3)
In [228]: alist
Out[228]: [array([0, 1, 2]), [2, 3], None]

Upvotes: 1

Arturo
Arturo

Reputation: 3779

Solution and typo (as Willem marked):

data2['sac']['startx'][0][0] = startx_buff

The index was off by a [0]

Upvotes: 0

Related Questions