valores de grupo en intervalos

Tengo una serie de pandas que contiene ceros y unos:

df1 = pd.Series([ 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0]) df1 Out[3]: 0 0 1 0 2 0 3 0 4 0 5 1 6 1 7 1 8 0 9 0 10 0 

Me gustaría crear un df2 de datos que contenga el inicio y el final de los intervalos con el mismo valor, junto con el valor asociado … df2 en este caso debe ser …

 df2 Out[5]: Start End Value 0 0 4 0 1 5 7 1 2 8 10 0 

Mi bash fue:

 from operator import itemgetter from itertools import groupby a=[next(group) for key, group in groupby(enumerate(df1), key=itemgetter(1))] df2 = pd.DataFrame(a,columns=['Start','Value']) 

pero no sé cómo conseguir los índices ‘Fin’

Puede groupby por Series que se crea por la cumsum de la Series cambiada df1 por shift .

Luego apply función de custum y la última remodelación por unstack .

 s = df1.ne(df1.shift()).cumsum() df2 = df1.groupby(s).apply(lambda x: pd.Series([x.index[0], x.index[-1], x.iat[0]], index=['Start','End','Value'])) .unstack().reset_index(drop=True) print (df2) Start End Value 0 0 4 0 1 5 7 1 2 8 10 0 

Otra solución con agregación por agg con first y last , pero hay más código necesario para manejar la salida por la salida deseada.

 s = df1.ne(df1.shift()).cumsum() d = {'first':'Start','last':'End'} df2 = df1.reset_index(name='Value') \ .groupby([s, 'Value'])['index'] \ .agg(['first','last']) \ .reset_index(level=0, drop=True) \ .reset_index() \ .rename(columns=d) \ .reindex_axis(['Start','End','Value'], axis=1) print (df2) Start End Value 0 0 4 0 1 5 7 1 2 8 10 0 

Podría usar el método pd.Series.diff() para identificar los índices iniciales:

 df2 = pd.DataFrame() df2['Start'] = df1[df1.diff().fillna(1) != 0].index 

Luego calcule los índices finales de esto:

 df2['End'] = [e - 1 for e in df2['Start'][1:]] + [df1.index.max()] 

Y por último reunir los valores asociados:

 df2['Value'] = df1[df2['Start']].values 

salida

  Start End Value 0 0 4 0 1 5 7 1 2 8 10 0 

Lo que está buscando es obtener el primer y último valor en un grupo

 import pandas as pd def first_last(df): return df.ix[[0,-1]] df = pd.DataFrame([3]*4+[4]*4+[1]*4+[3]*3,columns=['value']) print df df['block'] = (df.value.shift(1) != df.value).astype(int).cumsum() df = df.reset_index().groupby(['block','value'])['index'].agg(['first', 'last']).reset_index() del df['block'] print df 

Puede agruparse usando shift y cumsum y encontrar el primer y último índice válido

 df2 = df1.groupby((df1 != df1.shift()).cumsum()).apply(lambda x: np.ravel([x.index[0], x.index[-1], x.unique()])) df2 = pd.DataFrame(df2.values.tolist()).rename(columns = {0: 'Start', 1: 'End',2:'Value'}) 

Usted obtiene

  Start End Value 0 0 4 0 1 5 7 1 2 8 10 0