Un Pandas DataFrame
contiene una columna nombrada "date"
que contiene datetime
valores no únicos . Puedo agrupar las líneas en este marco usando:
data.groupby(data['date'])
Sin embargo, esto divide los datos por los datetime
valores. 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
dt
opción y jugar conweekofyear
,dayofweek
etc. 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
map
generalmente 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,
date
y 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 3
Hay varias formas de agrupar por año
year
propiedaddate
en índice y use la función anónima para acceder al añoresample
Método de uso.dt
accesor conyear
propiedadCuando 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
dt
descriptor de acceso. Por ejemplo:df['date'].dt.year 0 2012 1 2012 2 2015 3 2015 4 2015 Name: date, dtype: int64
Podemos 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 3
poner 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
dt
descriptor 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 3
Usa el
resample
métodoSi su columna de fecha no está en el índice, debe especificar la columna con el
on
pará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.0
Convertir 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: object
Entonces 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 3
fuente
to_period('A')
, ¿para qué es eso ('A')?'A'
is a timeseries offset-alias: pandas.pydata.org/pandas-docs/stable/….dt.year
mé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.