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.

Trace cada día individualmente en un gráfico extrayendo la hora de DatetimeIndex sin utilizar un bucle for.

Tengo un dataframe que incluye datos aleatorios durante 7 días y cada punto de datos está indexado por DatetimeIndex. Quiero graficar los datos de cada día en un solo gráfico. Actualmente, mi intento es el siguiente:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

n = 10000
i = pd.date_range('2018-04-09', periods=n, freq='1min')
ts = pd.DataFrame({'A': [np.random.randn() for i in range(n)]}, index=i)

dates = list(ts.index.map(lambda t: t.date()).unique())

for date in dates:
    ts['A'].loc[date.strftime('%Y-%m-%d')].plot()

El resultado es el siguiente:

Imagen

Como puedes ver, cuando se usa DatetimeIndex, se mantiene el día correspondiente, por eso tenemos cada día hacia atrás hasta el siguiente.

Preguntas:

1- ¿Cómo puedo corregir el código actual para tener un eje x que comience desde la medianoche y termine en la próxima medianoche?

2- ¿Existe una manera en pandas de agrupar mejor los días y graficarlos en un solo gráfico sin usar un bucle for?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para solucionar el código actual y tener un eje x que comience desde la medianoche y termine en la siguiente medianoche, debemos modificar las etiquetas del eje x para mostrar solo la componente de tiempo de la fecha y hora. Esto se puede lograr ajustando las etiquetas de xticklabels para que solo muestren la hora utilizando el método strftime(). También necesitamos usar el método loc[] para seleccionar los datos de cada día y luego establecer xlim para mostrar los datos durante 24 horas a partir de la medianoche. Aquí está el código modificado:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    n = 10000
    i = pd.date_range('2018-04-09', periods=n, freq='1min')
    ts = pd.DataFrame({'A': [np.random.randn() for i in range(n)]}, index=i)
    dates = ts.index.strftime('%Y-%m-%d').unique()
    
    fig, ax = plt.subplots()
    
    for date in dates:
        daily_data = ts.loc[date].reset_index(drop=True)
        ax.plot(daily_data, label=date)
    
    ax.set_xticklabels([t.strftime('%H:%M') for t in ax.get_xticks()])
    ax.set_xlim(pd.Timestamp('2018-04-09'), pd.Timestamp('2018-04-10'))
    ax.legend()
    plt.show()
    

    Sí, hay una manera de agrupar los días de manera más eficiente y representarlos en un solo día sin usar un bucle for. Podemos usar el método groupby() para agrupar los datos por día y luego usar el método plot() para representar los datos de cada día en un solo gráfico. Aquí está el código:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    n = 10000
    i = pd.date_range('2018-04-09', periods=n, freq='1min')
    ts = pd.DataFrame({'A': [np.random.randn() for i in range(n)]}, index=i)
    
    fig, ax = plt.subplots()
    ts.groupby(ts.index.date).plot(ax=ax)
    ax.set_xticklabels([t.strftime('%H:%M') for t in ax.get_xticks()])
    ax.set_xlim(pd.Timestamp('2018-04-09'), pd.Timestamp('2018-04-10'))
    plt.show()
    

Comments are closed.