对于一个3M元素的容器,这个答案比被接受的答案快了67.2倍。可以通过使用numpy将列表转换为numpy.array来实现。他的答案代码是从
Find index where elements change value numpy的代码修改而来的。
那个问题想要所有的过渡v[:-1] != v[1:],而不仅仅是这个问题中的小到大的过渡v[:-1] < v[1:]。
通过将数组与自身移位一位进行比较,创建一个布尔数组。使用
np.where
返回
True
的索引。
这会找到变化之前的索引,因为数组在比较时被移位了,所以使用+1来得到正确的值。
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]
v = np.array(v)
map_ = v[:-1] < v[1:]
idx = np.where(map_)[0] + 1
print(idx)
[out]:
array([ 7, 24], dtype=int64)
%timeit
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
%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)
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)
mot
是一个列表,那么这行代码会枚举除第一个元素外的所有元素,并将大于前一个元素的元素的索引和值作为一个元组返回。 - kabanus