title: Efficiently counting runs of non-zero values
body: <p>I am dealing with timeseries of rainfall volumes, for which I want to compute the lengths and volumes of individual rainfall events, where an "event" is a sequence of non-zero timesteps. I am dealing with multiple timeseries of ~60k timesteps and my current approach is quite slow.  </p>
  
  <p>Currently I have the following:</p>
  
  <pre><code>import numpy as np
  
  def count_events(timeseries):
      start = 0  
      end = 0
      lengths = []
      volumes = []
      # pad a 0 at the edges so as to include edges as "events"
      for i, val in enumerate(np.pad(timeseries, pad_width = 1, mode = 'constant')):
  
          if val &gt; 0 and start==0:
              start = i
          if val == 0 and start&gt;0:
              end = i
  
              if end - start != 1:
                  volumes.append(np.sum(timeseries[start:end]))
              elif end - start == 1:
                  volumes.append(timeseries[start-1])
  
              lengths.append(end-start)
              start = 0
  
      return np.asarray(lengths), np.asarray(volumes)
  </code></pre>
  
  <p>Expected output:</p>
  
  <pre><code>testrain = np.array([1,0,1,0,2,2,8,2,0,0,0.1,0,0,1])
  lengths, volumes = count_events(testrain)
  print lengths
  [1 1 4 1 1]
  print volumes
  [  1.    1.   12.    0.1   1. ] # 12 should actually be 14, my code returns wrong results.
  </code></pre>
  
  <p>I imagine there's a far better way to do this, leveraging numpy's efficiency, but nothing comes to mind... </p>
  
  <p>EDIT:</p>
  
  <p>Comparing the different solutions:</p>
  
  <pre><code>testrain = np.random.normal(10,5, 60000)
  testrain[testrain&lt;0] = 0 
  </code></pre>
  
  <p>My solution (produces wrong results, not exactly sure why):</p>
  
  <pre><code>%timeit count_events(testrain)
  #10 loops, best of 3: 129 ms per loop
  </code></pre>
  
  <p>@dawg's:</p>
  
  <pre><code>%timeit dawg(testrain) # using itertools
  #10 loops, best of 3: 113 ms per loop
  %timeit dawg2(testrain) # using pure numpy
  #10 loops, best of 3: 156 ms per loop
  </code></pre>
  
  <p>@DSM's:</p>
  
  <pre><code>%timeit DSM(testrain)
  #10 loops, best of 3: 28.4 ms per loop
  </code></pre>
  
  <p>@DanielLenz's:</p>
  
  <pre><code>%timeit DanielLenz(testrain)
  #10 loops, best of 3: 316 ms per loop
  </code></pre>