Estoy tratando de agregar una etiqueta a cada intervalo de 15 minutos en una nueva columna de mi Pandas df llamada Intervalo si la fecha y hora cae dentro de un rango de 15 minutos. He intentado cortar, qcut, strptime y mero sin éxito.

'''Basically I'd like to turn this:'''
    Date
    29/8/20 2:24       
    29/8/20 1:02
    29/8/20 0:26
    28/8/20 23:14
    28/8/20 21:57
    28/8/20 21:55
    28/8/20 21:46
    28/8/20 20:38
    28/8/20 19:40
    28/8/20 18:20
    
 '''Into this:'''
    Date             Interval
    29/8/20 2:24     Period 1
    29/8/20 1:02     Period 2
    29/8/20 0:26     Period 3
    28/8/20 23:14    Period 4
    28/8/20 21:57    Period 5
    28/8/20 21:55    Period 5
    28/8/20 21:46    Period 5
    28/8/20 21:35    Period 5
    28/8/20 19:40    Period 6
    28/8/20 18:20    Period 7
import datetime
import pandas as pd

s_date = datetime.datetime.now()
dates = [s_date]
for days in range(1, 5):
    for i in range(24 * 4):
        dates.append(dates[-1] + datetime.timedelta(minutes=15))
    dates.append(dates[0] + datetime.timedelta(days=days))

print(dates)

df['Interval'] = pd.cut(df['Date'], bins=dates, duplicates='drop', ordered=True, labels=labels,
                        right=False).cat.add_categories([i]).fillna(i)

# Save CSV File
csv_path = r'x'
df.to_csv(csv_path + 'x' + '.csv')
0
YUragun 29 ago. 2020 a las 07:36

1 respuesta

La mejor respuesta

Creo que no lo explicaste muy bien, pero creo que sé lo que estás tratando de lograr. Este problema tiene que ver con el PEDIDO. Con .grouper y .cut, ORDER no es relevante. Como tal, necesita usar .shift() para comparaciones por filas.

Esencialmente, parece que está tratando de agrupar los tiempos en el mismo período si la siguiente fila está dentro de los 15 minutos. Puede usar .shift() para comparar datos de una fila a la siguiente y calcular si los segundos son> 900 (es decir, 15 minutos) con dt.seconds > 900. Esto devolverá una serie de True o False. Luego, simplemente tome .cumsum() (que agrega 1 cuando hay un valor de True y 0 cuando False. Por último, puede cambiar el dtype a un cadena con .astype(str) y anteponer 'Period ' + al principio:

df['Date'] = pd.to_datetime(df['Date'])
df['Interval'] = 'Period ' + (((df.shift()['Date'] - df['Date']).dt.seconds > 900).cumsum() + 1).astype(str)

Out[5]: 
                 Date  Interval
0 2020-08-29 02:24:00  Period 1
1 2020-08-29 01:02:00  Period 2
2 2020-08-29 00:26:00  Period 3
3 2020-08-28 23:14:00  Period 4
4 2020-08-28 21:57:00  Period 5
5 2020-08-28 21:55:00  Period 5
6 2020-08-28 21:46:00  Period 5
7 2020-08-28 20:38:00  Period 6
8 2020-08-28 19:40:00  Period 7
9 2020-08-28 18:20:00  Period 8
1
David Erickson 29 ago. 2020 a las 05:05