NonSleeper
NonSleeper

Reputation: 851

How to find and replace values of even-positioned elements in sequence

I have a list as follows:

list_1 = [12, 15, 18, 21, 6, 9, 7, 21, 38, 62, 65, 68, 81, 21, 25, 96, 101, 8, 11]

There are sequences of elements whose value's distances are equal. In this list, that distance is 3, for example, 12, 15, 18, 21.

How can I replace the value of the even-positioned elements for each of these sequences / sublists with a new value, say -1. The output will be:

list_2 = [12, -1, 18, -1, 6, -1, 7, 21, 38, 62, -1, 68, 81, 21, 25, 96, 101, 8, -1]

Upvotes: 2

Views: 281

Answers (2)

yatu
yatu

Reputation: 88246

For a numpy based approach we could use np.diff to find the first differences of the array, and check if the items are even by taking 2 modulo of an np.arange. We can then chain both conditions with a bitwise AND, and slice assign back to a:

a = np.array([12, 15, 18, 21, 6, 9, 7, 21, 38, 62, 65, 68, 81, 21, 25, 96, 101, 8, 11])

m = (np.diff(a)==3) & (np.arange(1,len(a))%2==1)
a[1:] = np.where(m, -1, a[1:])

print(a)
array([ 12,  -1,  18,  -1,   6,  -1,   7,  21,  38,  62,  65,  -1,  81,
        21,  25,  96, 101,   8,  11])

Upvotes: 1

rafaelc
rafaelc

Reputation: 59274

Use diff()

s = pd.Series(list_1)
s.loc[(s.diff() == 3) & (s.index % 2 == 1)] = -1

which yields

[12, -1, 18, -1, 6, -1, 7, 21, 38, 62, 65, -1, 81, 21, 25, 96, 101, 8, 11]

Now, if you want the even positions related to each of those sequences independently, use groupby and cumcount

s.loc[s.groupby(s.diff().ne(3).cumsum()).cumcount() % 2 == 1] = -1

which yields

[12, -1, 18, -1, 6, -1, 7, 21, 38, 62, -1, 68, 81, 21, 25, 96, 101, 8, -1]

The difference will be the last -1 in your example. The first solution assumes the 11 shouldn't be replaced because it's not in an even position in your list_1. The second solutions assumes it should be replace, because it is in an even position in the sublist [8, 11].

Upvotes: 3

Related Questions