columns - pandas rename column by index
Pandas convierte la fecha y hora con una columna de zona horaria separada (2)
Aquí hay un enfoque vectorizado (repetirá df.time_zone.nunique()
veces):
In [2]: t
Out[2]:
datetime time_zone
0 2016-09-19 01:29:13 America/Bogota
1 2016-09-19 02:16:04 America/New_York
2 2016-09-19 01:57:54 Africa/Cairo
3 2016-09-19 11:00:00 America/Bogota
4 2016-09-19 12:00:00 America/New_York
5 2016-09-19 13:00:00 Africa/Cairo
In [3]: for tz in t.time_zone.unique():
...: mask = (t.time_zone == tz)
...: t.loc[mask, ''datetime''] = /
...: t.loc[mask, ''datetime''].dt.tz_localize(tz).dt.tz_convert(''UTC'')
...:
In [4]: t
Out[4]:
datetime time_zone
0 2016-09-19 06:29:13 America/Bogota
1 2016-09-19 06:16:04 America/New_York
2 2016-09-18 23:57:54 Africa/Cairo
3 2016-09-19 16:00:00 America/Bogota
4 2016-09-19 16:00:00 America/New_York
5 2016-09-19 11:00:00 Africa/Cairo
ACTUALIZAR:
In [12]: df[''new''] = df.groupby(''time_zone'')[''datetime''] /
.transform(lambda x: x.dt.tz_localize(x.name))
In [13]: df
Out[13]:
datetime time_zone new
0 2016-09-19 01:29:13 America/Bogota 2016-09-19 06:29:13
1 2016-09-19 02:16:04 America/New_York 2016-09-19 06:16:04
2 2016-09-19 01:57:54 Africa/Cairo 2016-09-18 23:57:54
3 2016-09-19 11:00:00 America/Bogota 2016-09-19 16:00:00
4 2016-09-19 12:00:00 America/New_York 2016-09-19 16:00:00
5 2016-09-19 13:00:00 Africa/Cairo 2016-09-19 11:00:00
Tengo un marco de datos con una columna para la zona horaria y una columna para la fecha y hora. Me gustaría convertir estos a UTC primero para unirme a otros datos, y luego tendré algunos cálculos para convertir de UTC a la zona horaria local del usuario eventualmente.
datetime time_zone
2016-09-19 01:29:13 America/Bogota
2016-09-19 02:16:04 America/New_York
2016-09-19 01:57:54 Africa/Cairo
def create_utc(df, column, time_format=''%Y-%m-%d %H:%M:%S''):
timezone = df[''TZ'']
df[column + ''_utc''] = df[column].dt.tz_localize(timezone).dt.tz_convert(''UTC'').dt.strftime(time_format)
df[column + ''_utc''].replace(''NaT'', np.nan, inplace=True)
df[column + ''_utc''] = pd.to_datetime(df[column + ''_utc''])
return df
Ese fue mi intento fallido. El error es que la verdad es ambigua, lo que tiene sentido porque la variable ''zona horaria'' se refiere a una columna. ¿Cómo me refiero al valor en la misma fila?
Editar: aquí hay algunos resultados de las respuestas a continuación en un día de datos (394,000 filas y 22 zonas horarias únicas). Edit2: agregué un grupo por ejemplo en caso de que alguien quiera ver los resultados. Es el más rápido, de lejos.
%%timeit
for tz in df[''TZ''].unique():
df.ix[df[''TZ''] == tz, ''datetime_utc2''] = df.ix[df[''TZ''] == tz, ''datetime''].dt.tz_localize(tz).dt.tz_convert(''UTC'')
df[''datetime_utc2''] = df[''datetime_utc2''].dt.tz_localize(None)
1 loops, best of 3: 1.27 s per loop
%%timeit
df[''datetime_utc''] = [d[''datetime''].tz_localize(d[''TZ'']).tz_convert(''UTC'') for i, d in df.iterrows()]
df[''datetime_utc''] = df[''datetime_utc''].dt.tz_localize(None)
1 loops, best of 3: 50.3 s per loop
df[''datetime_utc''] = pd.concat([d[''datetime''].dt.tz_localize(tz).dt.tz_convert(''UTC'') for tz, d in df.groupby(''TZ'')])
**1 loops, best of 3: 249 ms per loop**
Su problema es que tz_localize()
solo puede tomar un valor escalar, por lo que tendremos que iterar a través del DataFrame:
df[''datetime_utc''] = [d[''datetime''].tz_localize(d[''time_zone'']).tz_convert(''UTC'') for i,d in df.iterrows()]
El resultado es:
datetime time_zone datetime_utc
0 2016-09-19 01:29:13 America/Bogota 2016-09-19 06:29:13+00:00
1 2016-09-19 02:16:04 America/New_York 2016-09-19 06:16:04+00:00
2 2016-09-19 01:57:54 Africa/Cairo 2016-09-18 23:57:54+00:00
Un enfoque alternativo es agrupar por zona horaria y convertir todas las filas coincidentes en una sola pasada:
df[''datetime_utc''] = pd.concat([d[''datetime''].dt.tz_localize(tz).dt.tz_convert(''UTC'') for tz, d in df.groupby(''time_zone'')])