Un Pandas DataFramecontiene una columna nombrada "date"que contiene datetimevalores no únicos . Puedo agrupar las líneas en este marco usando:
data.groupby(data['date'])
Sin embargo, esto divide los datos por los datetimevalores. Me gustaría agrupar estos datos por el año almacenado en la columna "fecha". Esta página muestra cómo agrupar por año en los casos en los que la marca de tiempo se usa como índice, lo cual no es cierto en mi caso.
¿Cómo logro esta agrupación?

Respuestas:
Estoy usando pandas 0.16.2. Esto tiene un mejor rendimiento en mi gran conjunto de datos:
Usar la
dtopción y jugar conweekofyear,dayofweeketc. se vuelve mucho más fácil.fuente
La solución de ecatmur funcionará bien. Sin embargo, esto será un mejor rendimiento en grandes conjuntos de datos:
data.groupby(data['date'].map(lambda x: x.year))fuente
mapgeneralmente tiene algunas cualidades de eficiencia buenas cuando se aplican funciones arbitrarias en comparación con solo usarapply.Esto podría ser más fácil de explicar con un conjunto de datos de muestra.
Crear datos de muestra
Asumamos que tenemos una sola columna de marcas de tiempo,
datey la otra columna nos gustaría realizar una agregación en,a.df = pd.DataFrame({'date':pd.DatetimeIndex(['2012-1-1', '2012-6-1', '2015-1-1', '2015-2-1', '2015-3-1']), 'a':[9,5,1,2,3]}, columns=['date', 'a']) df date a 0 2012-01-01 9 1 2012-06-01 5 2 2015-01-01 1 3 2015-02-01 2 4 2015-03-01 3Hay varias formas de agrupar por año
yearpropiedaddateen índice y use la función anónima para acceder al añoresampleMétodo de uso.dtaccesor conyearpropiedadCuando tiene una columna (y no un índice) de marcas de tiempo de pandas, puede acceder a muchas más propiedades y métodos adicionales con el
dtdescriptor de acceso. Por ejemplo:df['date'].dt.year 0 2012 1 2012 2 2015 3 2015 4 2015 Name: date, dtype: int64Podemos usar esto para formar nuestros grupos y calcular algunas agregaciones en una columna en particular:
df.groupby(df['date'].dt.year)['a'].agg(['sum', 'mean', 'max']) sum mean max date 2012 14 7 9 2015 6 2 3poner la fecha en el índice y usar la función anónima para acceder al año
Si establece la columna de fecha como índice, se convierte en un DateTimeIndex con las mismas propiedades y métodos que el
dtdescriptor de acceso proporciona a las columnas normalesdf1 = df.set_index('date') df1.index.year Int64Index([2012, 2012, 2015, 2015, 2015], dtype='int64', name='date')Curiosamente, al usar el método groupby, puede pasarle una función. Esta función se pasará implícitamente al índice del DataFrame. Entonces, podemos obtener el mismo resultado de arriba con lo siguiente:
df1.groupby(lambda x: x.year)['a'].agg(['sum', 'mean', 'max']) sum mean max 2012 14 7 9 2015 6 2 3Usa el
resamplemétodoSi su columna de fecha no está en el índice, debe especificar la columna con el
onparámetro. También debe especificar el alias de desplazamiento como una cadena.df.resample('AS', on='date')['a'].agg(['sum', 'mean', 'max']) sum mean max date 2012-01-01 14.0 7.0 9.0 2013-01-01 NaN NaN NaN 2014-01-01 NaN NaN NaN 2015-01-01 6.0 2.0 3.0Convertir a período pandas
También puede convertir la columna de fecha en un objeto Pandas Period. Debemos pasar el alias de desplazamiento como una cadena para determinar la duración del período.
df['date'].dt.to_period('A') 0 2012 1 2012 2 2015 3 2015 4 2015 Name: date, dtype: objectEntonces podemos usar esto como un grupo
df.groupby(df['date'].dt.to_period('Y'))['a'].agg(['sum', 'mean', 'max']) sum mean max 2012 14 7 9 2015 6 2 3fuente
to_period('A'), ¿para qué es eso ('A')?'A'is a timeseries offset-alias: pandas.pydata.org/pandas-docs/stable/….dt.yearmétodo simple y lo guardo en un nuevo marco de datos, las fechas se guardan como índices y eso se vuelve problemático si digo que necesito trazar los datos porque la columna 'fechas' no está realmente allí, sino solo las tres proporcionado en.agg()Esto debería funcionar:
data.groupby(lambda x: data['date'][x].year)fuente
esto también funcionará
data.groupby(data['date'].dt.year)fuente
<pandas.core.groupby.DataFrameGroupBy object at 0x10d7f6438>es lo que obtengo cuando me ejecutan.