Conditional length of a binary data series in Pandas
<p>Having a DataFrame with the following column:</p>

<pre><code>df['A'] = [1,1,1,0,1,1,1,1,0,1]
</code></pre>

<p>What would be the best vectorized way to control the length of "1"-series by some limiting value? Let's say the limit is 2, then the resulting column 'B' must look like:</p>

<pre><code>   A  B
0  1  1
1  1  1
2  1  0
3  0  0
4  1  1
5  1  1
6  1  0
7  1  0
8  0  0
9  1  1
</code></pre>

<p>If you know that the values in the series will all be either <code>0</code> or <code>1</code>, I think you can use a little trick involving convolution. Make a copy of your column (which need not be a Pandas object, it can just be a normal Numpy array)</p>

<pre><code>a = df['A'].as_matrix()
</code></pre>

<p>and convolve it with a sequence of 1's that is one longer than the <code>cutoff</code> you want, then chop off the last <code>cutoff</code> elements. E.g. for a <code>cutoff</code> of 2, you would do</p>

<pre><code>long_run_count = numpy.convolve(a, [1, 1, 1])[:-2]
</code></pre>

<p>The resulting array, in this case, gives the number of <code>1</code>'s that occur in the 3 elements prior to and including that element. If that number is 3, then you are in a run that has exceeded length 2. So just set those elements to zero.</p>

<pre><code>a[long_run_count &gt; 2] = 0
</code></pre>

<p>You can now assign the resulting array to a new column in your <code>DataFrame</code>.</p>

<pre><code>df['B'] = a
</code></pre>

<p>To turn this into a more general method:</p>

<pre><code>def trim_runs(array, cutoff):
    a = numpy.asarray(array)
    a[numpy.convolve(a, numpy.ones(cutoff + 1))[:-cutoff] &gt; cutoff] = 0
    return a
</code></pre>

python pandas vectorization