Robin Tournemenne
Robin Tournemenne

Reputation: 104

vector manipulation in python

I have a vector of growing integers:

data = np.arange(6) + 1

I want to organize it in a bigger vector to the following indices:

dataIdx = np.array([1, 1, 0, 1, 1, 0, 0, 1, 1])

The result would then be:

array([1, 2, 0, 3, 4, 0, 0, 5, 6])

I can use a for-loop, but I am looking for a one-liner or two-liners.

Upvotes: 0

Views: 770

Answers (4)

hpaulj
hpaulj

Reputation: 231738

A variation on the where answer - turn DataIdx into a boolean mask with astype:

In [97]: data=np.arange(1,7)
In [98]: dataIdx = np.array([1, 1, 0, 1, 1, 0, 0, 1, 1])
In [99]: res = np.zeros(dataIdx.shape, data.dtype)

We don't want to index with the integer array

# In [100]: res[dataIdx] 
# Out[100]: array([0, 0, 0, 0, 0, 0, 0, 0, 0])

But make it boolean, with astype, or with dataIdx==1:

In [101]: res[dataIdx.astype(bool)]
Out[101]: array([0, 0, 0, 0, 0, 0])

In [102]: res[dataIdx.astype(bool)]=data
In [103]: res
Out[103]: array([1, 2, 0, 3, 4, 0, 0, 5, 6])

np.place(res, dataIdx.astype(bool), data) also works.

Upvotes: 0

mrCarnivore
mrCarnivore

Reputation: 5088

More general with lists:

from collections import deque

a_list = [1,2,3,4,5,6,7,8]
b_list = [1,1,0,0,1,1,1,0,1,1,0,0,1]

a_queue = deque(a_list)

d_list = [a_queue.popleft() if i else 0 for i in b_list ]

print(d_list)

Upvotes: 0

user3483203
user3483203

Reputation: 51185

Using cumsum and a mask:

dataIdx[dataIdx!=0] = dataIdx[dataIdx!=0].cumsum()
# array([1, 2, 0, 3, 4, 0, 0, 5, 6])

Upvotes: 1

Kasravnd
Kasravnd

Reputation: 107357

Here is one way:

In [53]: ind = np.where(dataIdx != 0)[0]

In [55]: z = np.zeros(dataIdx.size)

In [57]: z[ind] = data

In [58]: z
Out[58]: array([1., 2., 0., 3., 4., 0., 0., 5., 6.])

Upvotes: 1

Related Questions