0

I have two arrays, say,

n = [1,2,3,4,5,6,7,8,9]
nc = [3,0,2,0,1,2,0,0,0]

The nonzero elements in nc are ncz = [3,2,1,2]. The elements in n corresponding to non zero elements in nc are p = [1,3,5,6]. I need to create a new array with elements of p[1:] inserted after ncz.cumsum()[:-1]+1 i.e after [4,6,7] Is there any way to do this without using np.insert or a for loop? Suppose I have m such pairs of arrays. Would I be able to do the same thing for each pair without using a loop? The resulting arrays can be zero padded to bring them to the same shape. The result would be [1, 2, 3, 4, 3, 5, 6, 5, 7, 6, 8, 9]

To do it using np.insert, one would do:

n = np.array([1,2,3,4,5,6,7,8,9])
nc = np.array([3,0,2,0,1,2,0,0,0])
p1 = n[nc.nonzero()][1:]
ncz1 = nc[nc.nonzero()][:-1].cumsum()
result = np.insert(n,ncz1+1,p1)

I know how to do this using numpy insert operation, but I need to replicate it in theano and theano doesn't have an insert op.

1
  • Add the desired results to your question. Your verbal description isn't clear. You could also include code, iterative with insert if needed, that does that (you know, the verifiable example rigmarole). Commented Jul 29, 2016 at 16:34

1 Answer 1

1

Because of its generality np.insert is rather complex (but available for study), but for your case, with a 1d array, and order insert points, it can be simplified to

np.insert(n, i, p1) with:

In [688]: n
Out[688]: array([1, 2, 3, 4, 5, 6, 7, 8, 9])
In [689]: p1
Out[689]: array([13, 15, 16])
In [690]: i
Out[690]: array([4, 6, 7], dtype=int32)

Target array, z, and the insertion points in that array:

In [691]: j=i+np.arange(len(i))
In [692]: z=np.zeros(len(n)+len(i),dtype=n.dtype)

make a boolean mask - True where n values go, False where p1 values go.

In [693]: ind=np.ones(z.shape,bool)
In [694]: ind[j]=False
In [695]: ind
Out[695]: 
array([ True,  True,  True,  True, False,  True,  True, False,  True,
       False,  True,  True], dtype=bool)

copy values in to the right slots:

In [696]: z[ind]=n
In [697]: z[~ind]=p1    # z[j]=p1 would also work
In [698]: z
Out[698]: array([ 1,  2,  3,  4, 13,  5,  6, 15,  7, 16,  8,  9])

This is typical of array operations that return a new array of a different size. Make the target, and copy the appropriate values. This is true even when the operations are done in compiled numpy code (e.g. concatenate).

Sign up to request clarification or add additional context in comments.

4 Comments

It would not be possible to do my problem for the 2d case without a loop right?
In what sense is it 2d. np.insert handles 2d - insert rows or columns (not both in the same call). It's a little more complicated, but not difficult.
I'll add an example explaining what I mean by 2d.
I was able to extrapolate this to the 2d case. Thank you very much for your help. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.