How to find the index where values in a list, increase value

Question:

I have a list that looks like:

mot = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0]

I need to append to a list, the index when the element changes from 0 to 1 (and not from 1 to 0).

I’ve tried to do the following, but it also registers when it changes from 1 to 0.

i = 0 
while i != len(mot)-1:
    if mot[i] != mot[i+1]:
        mot_daily_index.append(i)
    i += 1

Also, but not as important, is there a cleaner implementation?

Asked By: hcp

||

Answers:

Here is how you can do that with a list comprehension:

mot = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0]
mot_daily_index = [i for i,m in enumerate(mot) if i and m and not mot[i-1]]
print(mot_daily_index)

Output:

[7, 24]

Explanation:

  • list(enumerate([7,5,9,3])) will return [(0, 7), (1, 5), (2, 9), (3, 3)], so the i in i for i, m in enumerate, is the index of m during that iteration.
Answered By: Ann Zen

Use a list comprehension with a filter to get your indexes:

mot = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0]

idx = [i for i,v in enumerate(mot) if i and v > mot[i-1]]
print(idx)

Output:

[7, 24]
Answered By: Patrick Artner
mot = [0,0,0,0,1,0,1,0,1,1,1,0,1,1,1,0,0,0,0]
mot_daily_index = [] # the required list
for i in range(len(a)-1):
    if a[i]==0 and a[i+1]==1:
        ind.append(i)

your code adds index whenever ith element is different from (i+1)th element

Answered By: Atharva Kadlag

You could use

lst = [0, 0, 0, 1, 1, 1, 0, 1]
#      0  1  2  3  4  5  6  7

for index, (x, y) in enumerate(zip(lst, lst[1:])):
    if x == 0 and y == 1:
        print("Changed from 0 to 1 at", index)

Which yields

Changed from 0 to 1 at 2
Changed from 0 to 1 at 6
Answered By: Jan

A oneliner using zip:

mot = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0]

[i+1 for i,m in enumerate(zip(mot[:-1],mot[1:])) if m[0]<m[1]]

# [7, 24]
Answered By: AnsFourtyTwo

Here’s a solution using itertools.groupby to group the list into 0’s and 1’s:

from itertools import groupby

mot = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0]

mot_daily_index = []
l = 0
for s, g in groupby(mot):
    if s == 1:
        mot_daily_index.append(l)
    l += len(list(g))

print(mot_daily_index)

Output:

[7, 24]
Answered By: Nick

Another list comprehension take:

mot = [0,1,1,1,1,0,0,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0]

change_mot = [index+1 for index, value in enumerate(zip(mot[:-1], mot[1:], )) if value[1] - value[0] == 1]

Which yields

[1, 8, 11, 15]

This picks up the increase and records the index only if the increase = 1.

Answered By: Kristin H
  • For a 3M element container, this answer is 67.2 times faster than the accepted answer.
  • This can be accomplished with numpy, by converting the list to a numpy.array.
  • The code for his answer, is a modification of the code from Find index where elements change value numpy.
    • That question wanted all transitions v[:-1] != v[1:], not just the small to large transitions, v[:-1] < v[1:], in this question.
  • Create a Boolean array, by comparing the array to itself, shifted by one place.
  • Use np.where to return the indices for True
    • This finds the index before the change, because the arrays are shifted for comparison, so use +1 to get the correct value.
import numpy as np

v = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0]

# convert to array
v = np.array(v)

# create a Boolean array
map_ = v[:-1] < v[1:]

# return the indices
idx = np.where(map_)[0] + 1

print(idx)
[out]:
array([ 7, 24], dtype=int64)

%timeit

# v is 3M elements
v = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0] * 100000

# accepted answer
%timeit [i for i,m in enumerate(v) if i and m and not v[i-1]]
[out]:
336 ms ± 14 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# this answer
v = np.array(v)
%timeit np.where(v[:-1] < v[1:])[0] + 1
[out]:
5.03 ms ± 85.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Answered By: Trenton McKinney
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.