def gap_count(ts,state="gap",dtype=int):        
    """ Count missing data
    Identifies gaps (runs of missing or non-missing data) and quantifies the
    length of the gap in terms of number of samples, which works better for
    regular series. Each time point receives the length of the run. 
    
    Parameters
    ----------
    
    ts : :class:`DataFrame <pandas:pandas.DataFrame>`
        Time series to analyze
        
    state : `str` one of 'gap'|'good'|'both'
        State to count. If state is gap, block size of missing data are counted 
        and reported for time points in the gap (every point in a given gap will
        receive the same value). Non missing data will have a size of zero. 
        Setting state to 'good' inverts this -- missing blocks are reported as
        zero and good data are counted. 
        
    dtype : `str` or `type`
        Data type of output, should be acceptable to
        pandas :meth:`astype <pandas:pandas.DataFrame.astype>`
    
    """   
    ts_out = ts.fillna(0).astype(dtype)
    s = ts.index.to_series()
    for c in ts.columns:
        #test missing values
        miss = ts[c].isna()
        #create consecutive groups that increment each time the "is missing state" (na or not na) changes
        g = miss.ne(miss.shift()).cumsum()

        # identify beginning (min time) of each state
        count = s.groupby(g).count()
                
        # g contains a group index for each member of out, and here
        # we map g to out which has cumulative time
        ts_out[c] = g.map(count)
        if state == "gap":
            ts_out.loc[~miss,c] = 0
        elif state == "good":
            ts_out.loc[miss,c] = 0
    return ts_out