es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Añadiendo columnas de zona horaria y fecha/hora en pandas

¿Es un bucle for la forma más eficiente de lograr lo siguiente? Parece estar funcionando, pero tarda mucho tiempo en 3 millones de filas (alrededor de 6 segundos para actualizar 100 filas, usando tz_localize, ¡o aproximadamente cinco horas!).

whois_timezone_info = { "A": 1 * 3600, "ACDT": 10 * 3600, ..., "CDT": -5 * 3600, ..., "EST": -5 * 3600, ...}

df = pd.DataFrame({
  't': ['2001-06-01T00:00:00', '2001-06-01T00:00:00'],
  'z': ['CDT', 'EST']
})

df['datetime'] = pd.to_datetime(df['t'])

<h1>No funciona, ya que .tz_localize espera una cadena</h1>

df['datetime-z'] = df['datetime'].dt.tz_localize(df['t'])

<h1>Funciona... Pero es muy lento en grandes DataFrames (por ejemplo, 3 millones de filas)</h1>

for idx, i in df.iterrows(): # int, [] values
  df.loc[idx, 'datetime-z'] = i['datetime'].tz_localize(
    tz=whois_timezone_info[i['t']]
  )
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    No, un bucle for no es la forma más eficiente de lograr el resultado deseado. En este caso, el rendimiento lento probablemente se deba al uso de iterrows(), que se sabe que es lento para grandes DataFrames. Un enfoque más eficiente sería utilizar la función map() para mapear los valores de la columna ‘t’ a sus correspondientes zonas horarias, según se define en el diccionario whois_timezone_info. El código se vería algo así:

    # Función de mapeo para convertir abreviaturas de zonas horarias a compensaciones UTC
    def convert_timezone(abbr):
        if abbr in whois_timezone_info:
            return pd.Timedelta(seconds=whois_timezone_info[abbr])
        else:
            return None
    
    # Aplicar la función de mapeo a la columna 'z'
    df['offset'] = df['z'].map(convert_timezone)
    
    # Utilizar el accesorio dt para convertir a la zona horaria especificada
    df['datetime-z'] = df['datetime'].dt.tz_localize('UTC').dt.tz_convert(df['offset'])
    

    Al utilizar map() en lugar de iterrows(), podemos evitar la sobrecarga de iterar sobre cada fila y, en su lugar, aplicar la función de mapeo a toda la columna a la vez. Esto debería resultar en un rendimiento mucho más rápido, incluso para grandes DataFrames.

Comments are closed.