[SciPy-User] numpy array assignment

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[SciPy-User] numpy array assignment

marco cammarata
Hi,

I have used many times syntax like

import numpy as np

def result_of_long_calculation_returning_the_right_shape():
  return np.random.random( (2,3) )


N=10
out = np.empty( (N,2,3) )
for i in range(N):
  out[i] = result_of_long_calculation_returning_the_right_shape()

if I have to loop trough the axis 1 I would do something like

N=10
out = np.empty( (2,N,3) )
for i in range(N):
  out[:,i,:] = result_of_long_calculation_returning_the_right_shape()

The problem is that - in the function I am writing - the number of
dimensions and the axis to loop trough are not known in advance.

Is there a smart what to do it ?
I would expect that a function like np.assign(array,element=0,axis=0) that  
but I can't find such function.

For the moment I ended up doing something really really inelegant:
  res = result_of_long_calculation_returning_the_right_shape()
  s = "out[" + (":,")*axis + "i" + (",:")*(nDim-axis-1) + "]=res"
  exec(s)

Thanks a lot in advance,
marco




_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: numpy array assignment

Antonino Ingargiola
On Thu, Apr 17, 2014 at 7:59 AM, marco cammarata <[hidden email]> wrote: 
For the moment I ended up doing something really really inelegant:
  res = result_of_long_calculation_returning_the_right_shape()
  s = "out[" + (":,")*axis + "i" + (",:")*(nDim-axis-1) + "]=res"
  exec(s)

When you do a[:, :, :], that's just syntactic sugar for a[(slice(None), slice(None), slice(None),)] (note that slice(None) means take all elements). In other words, the index of a ndarray is a tuple of objects/slices.

You can build the tuple programmatically. Another example:

    import numpy as np
    a = np.arange(1000).reshape(10, 5, 20)
    index = (slice(None), slice(0, 1), slice(None))
    a[index] = 3
    a

Cheers,
Antonio

 

_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: numpy array assignment

marco cammarata
Antonino Ingargiola <tritemio <at> gmail.com> writes:

>
>
> On Thu, Apr 17, 2014 at 7:59 AM, marco cammarata <marcocamma <at>
gmail.com> wrote: 

>
>
>
>
> For the moment I ended up doing something really really inelegant:
>   res = result_of_long_calculation_returning_the_right_shape()
>   s = "out[" + (":,")*axis + "i" + (",:")*(nDim-axis-1) + "]=res"
>   exec(s)
>
>
> When you do a[:, :, :], that's just syntactic sugar for a[(slice(None),
slice(None), slice(None),)] (note that slice(None) means take all elements).
In other words, the index of a ndarray is a tuple of objects/slices.

>
> You can build the tuple programmatically. Another example:
>
>     import numpy as np
>     a = np.arange(1000).reshape(10, 5, 20)
>     index = (slice(None), slice(0, 1), slice(None))
>
>     a[index] = 3
>     a
>
>
> Cheers,
> Antonio
>
>  
>
>
>
> _______________________________________________
> SciPy-User mailing list
> SciPy-User <at> scipy.org
> http://mail.scipy.org/mailman/listinfo/scipy-user
>

Antonio,

thanks for your comment.
Indeed your solution is better than mine because avoid the exec but would
still require the construction of the tuple by checking the axis and the
number of dimension.

What I was really looking for is a more general (compact) solution.

Thanks anyway,
ciao
marco



_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: numpy array assignment

Mark Daoust
Using slices and tuples, as suggested by Antonio, we can redo your original example like this:

    colon = (slice(None),)
    out[colon*axis+(i,)+colon*(nDim-axis-1,)]=result

Ellipsis, which represents "as many colons as are needed", can simplify it farther:

    out[colon*axis+(i,...)]=result

but numpy slicing always has an implied trailing ellipsis so, I think, this is equivalent:

    out[colon*axis+(i,)]=result

The ellipses are more useful if you have a "negative" axis, counting from the right instead of left. For example you can hit all but the last (-1) and second to last (-2) axis  with:

    out[...,i]=result
    out[...,i,:]=result

or all but axis (-n) with:

    out[(...,i)+colon*(n)] = result




Mark Daoust


> You can build the tuple programmatically. Another example:
>
>     import numpy as np
>     a = np.arange(1000).reshape(10, 5, 20)
>     index = (slice(None), slice(0, 1), slice(None))
>
>     a[index] = 3
>     a
>
>
> Cheers,
> Antonio
>

_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user