Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

function to return copy of np.array with some elements replaced

I have a Numpy array and a list of indices, as well as an array with the values which need to go into these indices.

The quickest way I know how to achieve this is:

In [1]: a1 = np.array([1,2,3,4,5,6,7])

In [2]: x = np.array([10,11,12])

In [3]: ind = np.array([2,4,5])

In [4]: a2 = np.copy(a1)

In [5]: a2.put(ind,x)

In [6]: a2
Out[6]: array([ 1,  2, 10,  4, 11, 12,  7])

Notice I had to make a copy of a1. What I'm using this for is to wrap a function which takes an array as input, so I can give it to an optimizer which will vary some of those elements.

So, ideally, I'd like to have something which returns a modified copy of the original, in one line, that works like this:

a2 = np.replace(a1, ind, x)

The reason for that is that I need to apply it like so:

def somefunction(a):
    ....

costfun = lambda x: somefunction(np.replace(a1, ind, x))

With a1 and ind constant, that would then give me a costfunction which is only a function of x.

My current fallback solution is to define a small function myself:

def replace(a1, ind, x):
    a2 = np.copy(a1)
    a2.put(ind,x)
    return(a2)

...but this appears not very elegant to me.

=> Is there a way to turn that into a lambda function?

like image 244
Zak Avatar asked Oct 29 '22 23:10

Zak


1 Answers

Well you asked for a one-liner, here's one using sparse matrices with Scipy's csr_matrix -

In [280]: a1 = np.array([1,2,3,4,5,6,7])
     ...: x = np.array([10,11,12])
     ...: ind = np.array([2,4,5])
     ...: 

In [281]: a1+csr_matrix((x-a1[ind], ([0]*x.size, ind)), (1,a1.size)).toarray()
Out[281]: array([[ 1,  2, 10,  4, 11, 12,  7]])
like image 162
Divakar Avatar answered Nov 02 '22 10:11

Divakar