series temporales de datos pandas - contando valores únicos durante últimas 24 horas cada 30 minutos

votos
1

Estoy tratando de medir la actividad de mensaje en un foro dado los datos para cada mensaje individual.

Para ello, me gustaría saber cuántos única / diferentes autores han publicado mensajes en las últimas 24 horas, a cada media hora (09:00, 09:30, 10:00, ...).

Tengo una pandas DataFrameinformación a grabar el mensaje. Un mensaje tiene un número de correos, el momento en que se publicó, y que lo escribió. Este es uno de mis datos:

>>> # import pandas as pd
>>> # here df is a pd.DataFrame
>>> print df.loc[:, ['Message Timestamp','Message Author']]

 Post#            Message Timestamp     Message Author
239257    2017-06-09 14:45:46-04:00   JTTLJTTLFBVTNJDF
239258    2017-06-09 14:09:51-04:00        Tvpfrnpvb22
239259    2017-06-09 13:54:13-04:00          Hpzb Tbxb
239260    2017-06-09 13:45:37-04:00      TbnFrbnTrbdfr
239261    2017-06-09 13:28:55-04:00   JTTLJTTLFBVTNJDF
239262    2017-06-09 13:20:23-04:00          njlftlj84
239263    2017-06-09 13:19:59-04:00      TbnFrbnTrbdfr
239264    2017-06-09 13:19:23-04:00   Vjtb Npvb Ttpdlt
239265    2017-06-09 13:15:03-04:00          njlftlj84
239266    2017-06-09 13:06:07-04:00      vndpnnpndfntt
239267    2017-06-09 12:48:54-04:00      TbnFrbnTrbdfr
239268    2017-06-09 12:16:59-04:00       Hrffn n Hpld
239269    2017-06-09 12:06:12-04:00             Xbllfr
239270    2017-06-09 11:27:33-04:00  TbttppfdTrbdfrFrz
239271    2017-06-09 11:21:46-04:00         ND`jn`BjhD
239272    2017-06-09 11:19:34-04:00      TbnFrbnTrbdfr
239273    2017-06-09 10:55:01-04:00      bbndpntfbdfll
239274    2017-06-09 10:55:01-04:00   JTTLJTTLFBVTNJDF
................(continued for years).................

Por ejemplo, el uso de los datos anteriores, vemos que el usuario JTTLJTTLFBVTNJDF ha publicado al menos tres veces en los últimos veinticuatro horas; esa persona sólo contribuye 1al número de autores únicos en los últimos veinticuatro horas.

La salida deseada se vería como la siguiente (dependiendo de las anteriores 24 horas de datos):

>>> print some_function(df, past='24 hours', every='30 mins')
 Index                        Number_of_unique_authors_in_the_last_24_hours
 2017-06-09 15:00:00-04:00                                               12
 2017-06-09 14:30:00-04:00                                               11
 2017-06-09 14:00:00-04:00                                               13
 ...(and so forth)......

Para mayor claridad, esto es decir a las 15:00, había 12 diferentes personas que habían enviado mensajes en los últimos veinte y cuatro horas, con base en los datos.

He probado diferentes combinaciones de pd.Timestamp.ceil, groupbyy rolling, pero nada cerca de lo que quiero. Una persona con experiencia podría saber la combinación correcta de cosas que hacer.

Además, hágamelo saber si alguien tiene una idea mejor título.


Edit: Estoy un poco sorprendido por debajo de algo así como que no funciona.

 series = df.set_index('Message Timestamp')['Message Author']
 series.resample('30 min').rolling('1D').nunique() #not supported

Yo sé cómo conseguir un bucle para hacer lo que quiero, pero sería bueno encontrar una manera de pandas de maniobras de hacer las cosas.

Publicado el 09/06/2017 a las 23:36
fuente por usuario
En otros idiomas...                            


2 respuestas

votos
1

Yo no era capaz de llegar a alguna solución elegante, pero una fuerza brutal de uno en bucle a través de la trama de datos, es de esperar que va a funcionar si su conjunto de datos no es enorme:

time, unique_count = [], []

for i in range(len(df)):

    time.append(t)
    t = df.ix[i, 'Time']

    #get the datetime of 24 hours ago
    yesterday = t - timedelta(days=1)

    #filter the original dataframe and count unique authors
    count = len(df.ix[(df['Time']<=t) &
            (df['Time']>=yesterday),'Author'].unique())
    unique_count.append(count)


result = pd.DataFrame({'Time': time, 
         'Number_of_unique_authors':unique_count})

Esperando a alguien para llegar a una solución más elegante.

Respondida el 10/06/2017 a las 00:02
fuente por usuario

votos
1

Considere resampleagregar a intervalos de 30 minutos y luego ejecutar nunique. Y luego ejecutar una transformde agregar nueva columna condicionalmente la cuenta única para cada 24 horas. Usted tendría que establecer primero la marca de tiempo como índice para volver a muestrear y luego de vuelta como columna regular a agregarse a las 24 horas.

import datetime
import pandas as pd
...
df = df[['Message Timestamp', 'Message Author']]

df['24-HourCount'] = df.transform(lambda x:\
          len(df[(df['Message Timestamp'].between(x['Message Timestamp'] - datetime.timedelta(days=1),
                                                  x['Message Timestamp']))]['Message Author'].unique()), axis=1)                                                       
df = df.set_index('Message Timestamp')                                               
df = df[['24-HourCount']].resample('30T').max()

print(df)  
#                      24-HourCount
# Message Timestamp                
# 2017-06-09 14:30:00           2.0
# 2017-06-09 15:00:00           5.0
# 2017-06-09 15:30:00           NaN
# 2017-06-09 16:00:00           7.0
# 2017-06-09 16:30:00           7.0
# 2017-06-09 17:00:00          10.0
# 2017-06-09 17:30:00          11.0
# 2017-06-09 18:00:00          12.0
# 2017-06-09 18:30:00          12.0
Respondida el 10/06/2017 a las 00:40
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more