tutorial name index columns column change pandas pytz

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'')])