2
votes

I have a 3d numpy array, A. the deminsions of the different elemnts is not equal to each other, i.e. the shape(A[0]) = (1,2), shape(A[1]) = (3,4), etc. I want to set the value of all the elements of A to zero the in the most efficient way. How can I do that?

thanks!

2
I'm a little confused here ... generally, a numpy array has a single shape, not multiple shapes. Do you have a list or tuple of 2d numpy arrays? - mgilson
I defiend it this way: A = np.array( [ [[1,2],[3,4]], [[1,2,3],[4,5,6],[7,8,9]] ] ) - user1767774
So you have an array of objects -- which is different than a 3d array. (notice that dtype=object). Out of curiosity, what are you doing with this array of objects? Generally there aren't a lot of advantages that you get from this sort of data-structure. - mgilson
well, it should hold the values of the weights of artificial neural network...I am quite new to numpy, so If you have better option for this purpose, I'll be happy to hear. - user1767774

2 Answers

2
votes

What you have is an np.array which is holding objects -- In your specific case, those objects are lists which hold more lists. This isn't a terribly good data structure for anything that I can think of unless you really need to be adding lots of elements to the inner lists. Might I propose a slight change to have an np.array which holds more np.arrays?

A = np.array(map(np.array, [ [[1,2],[3,4]], [[1,2,3],[4,5,6],[7,8,9]] ] ))

Now if we print it, it looks something like this:

>>> A
array([[[1 2]
 [3 4]], [[1 2 3]
 [4 5 6]
 [7 8 9]]], dtype=object)

And setting things to 0 becomes particularly easy:

for sub_array in A:
    sub_array[...] = 0

And for the proof (printing A again):

>>> A
array([[[0 0]
 [0 0]], [[0 0 0]
 [0 0 0]
 [0 0 0]]], dtype=object)
1
votes

Edit: Sorry, I didn't realize you created A from lists of lists of different sizes. My code shouldn't work unless you convert each element of A to an np.array using np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) for example.

You can try array-slicing or using NumPy's own iter function for ndarray's, called np.nditer:

In [7]: %%time
   ...: for arr in A:
   ...:     arr[:] = 0
   ...:
CPU times: user 43 µs, sys: 13 µs, total: 56 µs
Wall time: 52.9 µs

In [8]: %%time
   ...: for arr in A:
   ...:     for x in np.nditer(arr, op_flags=('readwrite',)):
   ...:         x[...] = 0
   ...:
CPU times: user 42 µs, sys: 5 µs, total: 47 µs
Wall time: 47 µs

Documentation can be read here.

Also, since A is an ndarray that doesn't hold numbers, but rather holds references to other ndarray's (check A's dtype. It should be object), you shouldn't call np.nditer on A itself, but rather on the referenced arrays inside A. Otherwise, A's structure is destroyed:

In [9]: %%time
   ...: for arr in np.nditer(A, flags=('refs_ok',), op_flags=('readwrite',)):
   ...:     for x in np.nditer(arr, flags=('refs_ok',), op_flags=('readwrite',)):
   ...:         x[...] = 12
   ...:
CPU times: user 31 µs, sys: 2 µs, total: 33 µs
Wall time: 34.1 µs

In [10]: A
Out[10]: array([12, 12], dtype=object)