Números del día en el mes

Tengo un dataframe con un índice de fecha y hora, y me gustaría multiplicar algunas columnas con el número de días en ese mes.

TUFNWGTP TELFS t070101 t070102 t070103 t070104 TUDIARYDATE 2003-01-03 8155462.672158 2 0 0 0 0 2003-01-04 1735322.527819 1 0 0 0 0 2003-01-04 3830527.482672 2 60 0 0 0 2003-01-02 6622022.995205 4 0 0 0 0 2003-01-09 3068387.344956 1 0 0 0 0 

Aquí, me gustaría multiplicar todas las columnas que comienzan con t con 31. Es decir, la salida esperada es

  TUFNWGTP TELFS t070101 t070102 t070103 t070104 TUDIARYDATE 2003-01-03 8155462.672158 2 0 0 0 0 2003-01-04 1735322.527819 1 0 0 0 0 2003-01-04 3830527.482672 2 1680 0 0 0 2003-01-02 6622022.995205 4 0 0 0 0 2003-01-09 3068387.344956 1 0 0 0 0 

Sé que hay algunas maneras de usar el calendar o similar, pero dado que ya estoy usando pandas , debe haber una manera más fácil, supongo.

No hay tal propiedad de datetime y datetime , pero hay un desplazamiento M , pero no sé cómo lo usaría sin una ineficiencia masiva.

Ahora hay un atributo Series.dt.daysinmonth para la serie datetime. Aquí hay un ejemplo basado en la respuesta de Jeff.

 In [3]: df = pd.DataFrame({'date' : pd.date_range('20120101',periods=15,freq='M') }) In [4]: df['year'] = df['date'].dt.year In [5]: df['month'] = df['date'].dt.month In [6]: df['days_in_month'] = df['date'].dt.daysinmonth In [7]: df Out[7]: date year month days_in_month 0 2012-01-31 2012 1 31 1 2012-02-29 2012 2 29 2 2012-03-31 2012 3 31 3 2012-04-30 2012 4 30 4 2012-05-31 2012 5 31 5 2012-06-30 2012 6 30 6 2012-07-31 2012 7 31 7 2012-08-31 2012 8 31 8 2012-09-30 2012 9 30 9 2012-10-31 2012 10 31 10 2012-11-30 2012 11 30 11 2012-12-31 2012 12 31 12 2013-01-31 2013 1 31 13 2013-02-28 2013 2 28 14 2013-03-31 2013 3 31 

pd.tslib.monthrange es una función no pd.tslib.monthrange / no documentada que maneja el cálculo de days_in_month (ajuste por años bisiestos). Esto podría / debería ser agregado como una propiedad a Timestamp/DatetimeIndex .

 In [34]: df = DataFrame({'date' : pd.date_range('20120101',periods=15,freq='M') }) In [35]: df['year'] = df['date'].dt.year In [36]: df['month'] = df['date'].dt.month In [37]: df['days_in_month'] = df.apply(lambda x: pd.tslib.monthrange(x['year'],x['month'])[1], axis=1) In [38]: df Out[38]: date year month days_in_month 0 2012-01-31 2012 1 31 1 2012-02-29 2012 2 29 2 2012-03-31 2012 3 31 3 2012-04-30 2012 4 30 4 2012-05-31 2012 5 31 5 2012-06-30 2012 6 30 6 2012-07-31 2012 7 31 7 2012-08-31 2012 8 31 8 2012-09-30 2012 9 30 9 2012-10-31 2012 10 31 10 2012-11-30 2012 11 30 11 2012-12-31 2012 12 31 12 2013-01-31 2013 1 31 13 2013-02-28 2013 2 28 14 2013-03-31 2013 3 31 

Aquí hay un pequeño método hecho a mano para obtener la cantidad de días en un mes.

 import datetime def days_in_month(dt): next_month = datetime.datetime( dt.year + dt.month / 12, dt.month % 12 + 1, 1) start_month = datetime.datetime(dt.year, dt.month, 1) td = next_month - start_month return td.days 

Por ejemplo:

 >>> days_in_month(datetime.datetime.strptime('2013-12-12', '%Y-%m-%d')) 31 >>> days_in_month(datetime.datetime.strptime('2013-02-12', '%Y-%m-%d')) 28 >>> days_in_month(datetime.datetime.strptime('2012-02-12', '%Y-%m-%d')) 29 >>> days_in_month(datetime.datetime.strptime('2012-01-12', '%Y-%m-%d')) 31 >>> days_in_month(datetime.datetime.strptime('2013-11-12', '%Y-%m-%d')) 30 

Te dejo saber cómo leer tu tabla y hacer la multiplicación tú mismo 🙂

 import pandas as pd from pandas.tseries.offsets import MonthEnd df['dim'] = (pd.to_datetime(df.index) + MonthEnd(0)).dt.day 

Puede omitir pd.to_datetime() , si su índice ya es DatetimeIndex .