将序列中的0替换为0

Sei*_*rra 5 python numpy

我有一个巨大的1和0的列表,如下所示:

x = [1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1].  
Run Code Online (Sandbox Code Playgroud)

完整列表在这里.

我想创建一个新的列表y,其条件是,只有当它们以> = 10的顺序出现时才应该保留1,否则那些1应该用零替换.
基于x以上^的ex ,y应该成为:

y = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1].  
Run Code Online (Sandbox Code Playgroud)

到目前为止,我有以下内容:

  1. 找出发生变化的地方和
  2. 找出以什么频率发生的序列:

import numpy as np
import itertools
nx = np.array(x)
print np.argwhere(np.diff(nx)).squeeze()

answer = []
for key, iter in itertools.groupby(nx):
    answer.append((key, len(list(iter))))
print answer
Run Code Online (Sandbox Code Playgroud)

这给了我:

[0 3 8 14]  # A
[(1, 1), (0, 3), (1, 5), (0, 6), (1, 10)] # B
Run Code Online (Sandbox Code Playgroud)

#A 这意味着在第0,第3等位置之后发生了变化.

#B 意味着有一个1,然后是三个0,然后是五个1,然后是6个零,接着是10个1.

如何y根据序列长度继续创建我们将用0替换1的位置的最后一步?

PS:##我对所有优秀人才的精彩解决方案感到谦卑.

jua*_*aga 6

只需在迭代分组时进行检查.就像是:

>>> from itertools import groupby
>>> x = [1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1]
>>> result = []
>>> for k, g in groupby(x):
...     if k:
...         g = list(g)
...         if len(g) < 10:
...             g = len(g)*[0]
...     result.extend(g)
...
>>> result
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Run Code Online (Sandbox Code Playgroud)

请注意,pandas对于此大小的数据集,这比相应的解决方案更快:

In [11]: from itertools import groupby

In [12]: %%timeit
    ...: result = []
    ...: for k, g in groupby(x):
    ...:     if k:
    ...:         g = list(g)
    ...:         if len(g) < 10:
    ...:             g = len(g)*[0]
    ...:     result.extend(g)
    ...:
181 µs ± 1.72 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [13]: %%timeit s = pd.Series(x)
    ...: s[s.groupby(s.ne(1).cumsum()).transform('count').lt(10)] = 0
    ...:
4.03 ms ± 176 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)

请注意,这是大熊猫解决方案的慷慨,不计算任何时间从列表转换pd.Series或转换回来,包括那些:

In [14]: %%timeit
    ...: s = pd.Series(x)
    ...: s[s.groupby(s.ne(1).cumsum()).transform('count').lt(10)] = 0
    ...: s = s.tolist()
    ...:
4.92 ms ± 119 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)