Extraer solo el mes y el año de la columna Datetime de Pandas

Tengo un Dataframe, df, con la siguiente columna:

df['ArrivalDate'] = ... 936 2012-12-31 938 2012-12-29 965 2012-12-31 966 2012-12-31 967 2012-12-31 968 2012-12-31 969 2012-12-31 970 2012-12-29 971 2012-12-31 972 2012-12-29 973 2012-12-29 ... 

Los elementos de la columna son pandas.tslib.Timestamp.

Solo quiero incluir el año y el mes. Pensé que habría una forma simple de hacerlo, pero no puedo entenderlo.

Esto es lo que he intentado:

 df['ArrivalDate'].resample('M', how = 'mean') 

Tuve el siguiente error:

 Only valid with DatetimeIndex or PeriodIndex 

Entonces intenté:

 df['ArrivalDate'].apply(lambda(x):x[:-2]) 

Tuve el siguiente error:

 'Timestamp' object has no attribute '__getitem__' 

¿Alguna sugerencia?

Edit: Me di cuenta de eso.

 df.index = df['ArrivalDate'] 

Luego, puedo volver a muestrear otra columna usando el índice.

Pero todavía me gustaría un método para reconfigurar toda la columna. ¿Algunas ideas?

Puede acceder directamente a los atributos de year y month , o solicitar un datetime.datetime :

 In [15]: t = pandas.tslib.Timestamp.now() In [16]: t Out[16]: Timestamp('2014-08-05 14:49:39.643701', tz=None) In [17]: t.to_pydatetime() #datetime method is deprecated Out[17]: datetime.datetime(2014, 8, 5, 14, 49, 39, 643701) In [18]: t.day Out[18]: 5 In [19]: t.month Out[19]: 8 In [20]: t.year Out[20]: 2014 

Una forma de combinar año y mes es hacer un entero que los codifique, por ejemplo: 201408 para agosto de 2014. A lo largo de toda la columna, puede hacer esto como:

 df['YearMonth'] = df['ArrivalDate'].map(lambda x: 100*x.year + x.month) 

o muchas variantes de los mismos.

Sin embargo, no soy un gran fanático de hacer esto, ya que hace que la alineación de las fechas y la aritmética sean más tarde dolorosas y especialmente dolorosas para otros que se encuentran con su código o datos sin esta misma convención. Una mejor manera es elegir una convención del día del mes, como el último día de la semana no festivo de los Estados Unidos, o el primer día, etc., y dejar los datos en un formato de fecha / hora con la convención de la fecha elegida.

El módulo de calendar es útil para obtener el valor numérico de ciertos días, como el último día de la semana. Entonces podrías hacer algo como:

 import calendar import datetime df['AdjustedDateToEndOfMonth'] = df['ArrivalDate'].map( lambda x: datetime.datetime( x.year, x.month, max(calendar.monthcalendar(x.year, x.month)[-1][:5]) ) ) 

Si está buscando una manera de resolver el problema más simple de simplemente formatear la columna datetime en alguna representación de cadena, puede usar la función strftime de la clase datetime.datetime , como esto:

 In [5]: df Out[5]: date_time 0 2014-10-17 22:00:03 In [6]: df.date_time Out[6]: 0 2014-10-17 22:00:03 Name: date_time, dtype: datetime64[ns] In [7]: df.date_time.map(lambda x: x.strftime('%Y-%m-%d')) Out[7]: 0 2014-10-17 Name: date_time, dtype: object 

Si desea nuevas columnas que muestren el año y el mes por separado, puede hacer esto:

 df['year'] = pd.DatetimeIndex(df['ArrivalDate']).year df['month'] = pd.DatetimeIndex(df['ArrivalDate']).month 

o…

 df['year'] = df['ArrivalDate'].dt.year df['month'] = df['ArrivalDate'].dt.month 

Entonces puedes combinarlos o trabajar con ellos tal como son.

La mejor manera encontrada !!

La date_column debe estar en formato de fecha y hora.

 df['month_year'] = df.date_column.dt.to_period('M') 

También puede usar D para el día, 2M durante 2 meses, etc. para diferentes intervalos de muestreo, y en el caso de que uno tenga datos de series de tiempo con sello de tiempo, podemos 45Min intervalos de muestreo granulares como 45Min durante 45 min, 15Min para 15Min 15 min. etc.

Si quieres el mes único del año, usar Apply es bastante elegante.

  df['mnth_yr'] = df['date_column'].apply(lambda x: x.strftime('%B-%Y')) 

Salidas mes-año en una columna.

no olvide cambiar primero el formato a fecha y hora antes, generalmente olvido: |

  df['date_column'] = pd.to_datetime(df['date_column']) 

Extraer el año digamos de [‘2018-03-04’]

 df['Year'] = pd.DatetimeIndex(df['date']).year 

El df [‘Año’] crea una nueva columna. Mientras que si quieres extraer el mes solo usa .month

Gracias a jaknap32 , quería agregar los resultados de acuerdo con el año y el mes, así que esto funcionó:

 df_join['YearMonth'] = df_join['timestamp'].apply(lambda x:x.strftime('%Y%m')) 

La salida fue ordenada:

 0 201108 1 201108 2 201108 

La solución de @KieranPC es el enfoque correcto para Pandas, pero no es fácilmente extensible para atributos arbitrarios. Para esto, puede usar getattr dentro de la comprensión de un generador y combinar usando pd.concat :

 list_of_dates = ['2012-12-31', '2012-12-29', '2012-12-30'] df = pd.DataFrame({'ArrivalDate': pd.to_datetime(list_of_dates)}) L = ['year', 'month', 'day', 'dayofweek', 'dayofyear', 'weekofyear', 'quarter'] df = df.join(pd.concat((getattr(df['ArrivalDate'].dt, i).rename(i) for i in L), axis=1)) print(df) ArrivalDate year month day dayofweek dayofyear weekofyear quarter 0 2012-12-31 2012 12 31 0 366 1 4 1 2012-12-29 2012 12 29 5 364 52 4 2 2012-12-30 2012 12 30 6 365 52 4 

Primero puede convertir sus cadenas de fecha con pandas.to_datetime , que le da acceso a todas las instalaciones de datetime y timedelta numpy . Por ejemplo:

 df['ArrivalDate'] = pandas.to_datetime(df['ArrivalDate']) df['Month'] = df['ArrivalDate'].values.astype('datetime64[M]') 
 df['year_month']=df.datetime_column.apply(lambda x: str(x)[:7]) 

Esto funcionó bien para mí, no pensé que los pandas interpretarían la fecha de la cadena resultante como la fecha, pero cuando hice la ttwig, conocía muy bien mi agenda y la cadena de year_month donde se ordenó correctamente … ¡hay que amar a los pandas!