Removing consecutive occurrences from end of list python
I have a numpy array:
ar = np.array([True, False, True, True, True])
If the last element is True, I want to remove all of the consecutive true elements at the end of the array. So for example
magic_func(ar) => [True, False]
If ar = [True, False, True, False, True]
. Then
magic_func(ar) => [True, False, True, False]
If ar = [True, False, False]
, the function does nothing, because the last element is False
Is there a one liner in python to do this? using a numpy library or something
This one line function should work, but looks very nasty and probably not efficient lol. Basically the idea is to find the most right False
and return all values before False
def magic_func(a):
return a[:len(a)-np.where(a[::-1]==False)[0][0]] if np.where(a[::-1]==False)[0].size>0 else a[:0]
>>> a = np.array([False, True, True, True, True])
>>> magic_func(a)
array([False], dtype=bool)
Use itertools.dropwhile
and np.fromiter
like this.
from itertools import dropwhile
np.fromiter(dropwhile(lambda x: x, ar[::-1]), dtype=bool)[::-1]
Edit
This is more faster way.(Just use itertools.takewhile
)
from itertools import takewhile
ar[:-sum(1 for i in takewhile(lambda x: x, reversed(ar)))]
Time:
ar = np.array([True, False, True, True, True])
#mine
%timeit ar[:-sum(1 for i in takewhile(lambda x: x, reversed(ar)))]
1000000 loops, best of 3: 1.84 us per loop
#mine
%timeit np.fromiter(dropwhile(lambda x: x, ar[::-1]), dtype=bool)[::-1]
100000 loops, best of 3: 2.93 us per loop
#@Jaime
%timeit ar[np.bitwise_or.accumulate(~ar[::-1])[::-1]]
100000 loops, best of 3: 3.63 us per loop
#@askewchan
%timeit ar[:len(ar)-np.argmin(ar[::-1])]
100000 loops, best of 3: 6.24 us per loop
#@xbb
%timeit ar[:len(ar)-np.where(ar[::-1]==False)[0][0]] if np.where(ar[::-1]==False)[0].size>0 else ar[:0]
100000 loops, best of 3: 7.61 us per loop
PS:
This is no-magic function.
def no_magic_func(ar):
for i in xrange(ar.size-1, -1, -1):
if not ar[i]:
return ar[:i+1]
return ar[0:0]
Time:
ar = np.array([True, False, True, True, True])
%timeit no_magic_func(ar)
1000000 loops, best of 3: 954 ns per loop
This is a little too magic for my liking, but it does seem to work nicely:
>>> ar = np.array([True, False, True, True, True])
>>> ar[np.bitwise_or.accumulate(~ar[::-1])[::-1]]
array([ True, False], dtype=bool)
To understand what's going on, first we negate the array, turning the True
s into False
s and viceversa, then we reverse the order, then we accumulate the result of OR-ing the array: this will be False
until the first True
, and will remain True
thereafter. reversing this array, we have a boolean indexing array that will get rid of all trailing True
s.
上一篇: 的node.js
下一篇: 从列表末尾删除连续的事件