Home > front end >  how could I create an array of the last marked value from an index array
how could I create an array of the last marked value from an index array

Time:07-08

I'm kind of new to python and not really used to a lot of the syntax yet. I would like to know how to get an array of the last value that has been marked as a 1 from an index array. For example for

idx = [1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1]

values = [23, 45, 78, 37, 15, 172, 45, 8, 16, 99, 55]

The desired array would look like

[23, 23, 23, 37, 37, 37, 37, 8, 16, 16, 55]

The sample code I'm working with uses xarray to create the index array, so maybe it could also be used to get the final array. Thanks for any help or suggestions

Edit: the length of both arrays will be the same, and if the index array starts with a 0, the output should be 0 until there is a 1 in the idx array

CodePudding user response:

You could use list comprehension with an assignment expression:

flags = [1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1]
values = [23, 45, 78, 37, 15, 172, 45, 8, 16, 99, 55]

prev = 0
result = [(prev := value) if flag else prev 
          for value, flag in zip(values, flags)]

print(result)  # [23, 23, 23, 37, 37, 37, 37, 8, 16, 16, 55]

CodePudding user response:

Let's call them arrayA and arrayB. And output array as arrayC. The algorithm would look like:


    check_index = 0
    for each_index in range(len(arrayA)):
      if arrayA[each_index] == 1:
        append(arrayC, arrayB[check_index])
        # this bumps the index to the next value
        check_index  = 1
    
      else:
        append(arrayC, arrayB[check_index])
        # otherwise, the index would stay the same


CodePudding user response:

A good use case for an assignment expression (aka walrus operator):

index = [1,0,0,1,0,0,0,1,1,0,1]

arr = [23,45,78,37,15,172,45,8,16,99,55]

result = []
last = 0

for x, i in zip(arr, index):
    result.append(last := x if i else last)

CodePudding user response:

You could use a simple list comprehension to filter the data. Below ln will equal the last dat with a matching 1 cmp.

cmp = [1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1]
dat = [23, 45, 78, 37, 15, 172, 45, 8, 16, 99, 55]

ln=0
print([ln:=d if c else ln for c,d in zip(cmp,dat)])

CodePudding user response:

You could do this in xarray, something along these lines:

import numpy as np, xarray as xr
mask = xr.DataArray([1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1], dims=['x'])
values = xr.DataArray([23, 45, 78, 37, 15, 172, 45, 8, 16, 99, 55], dims=['x'])

index = xr.DataArray(np.arange(len(mask)), dims=['x']).where(mask).ffill('x').astype(int)

You could then use this index to select positionally from values:

In [3]: index
Out[3]:
<xarray.DataArray (x: 11)>
array([ 0,  0,  0,  3,  3,  3,  3,  7,  8,  8, 10])
Dimensions without coordinates: x

In [4]: values.isel(x=index)
Out[4]:
<xarray.DataArray (x: 11)>
array([23, 23, 23, 37, 37, 37, 37,  8, 16, 16, 55])
Dimensions without coordinates: x

For something of this size, the list comprehension is much simpler and faster though.

  • Related