Pandas时间序列数据 - 每30分钟过去24小时内计算唯一值

时间:2017-06-10 02:37:00

标签: python python-2.7 pandas time-series pandas-groupby

我正在尝试在给定每条消息的数据的论坛上测量消息活动。

为此,我想知道有多少独特/不同作者在过去24小时内每隔半小时(9:00,9:30,10:00)发布消息,...)。

我有一个pandas DataFrame来记录消息信息。消息包含帖子编号,发布时间以及编写者。这是我的一些数据:

>>> # 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).................

例如,使用上述数据,我们看到用户" JTTLJTTLFBVTNJDF "在过去的24小时内至少发布过三次;该人仅在过去二十四小时内为{34}个独立作者提供了1"。

所需的输出如下所示(取决于之前24小时的数据):

>>> 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)......

为清楚起见,这是在15:00说,根据数据,在过去的二十四小时内有12个不同的人发布了消息。

我尝试了pd.Timestamp.ceilgroupbyrolling的不同组合,但没有接近我想要的内容。有经验的人可能知道要做的事情的正确组合。

另外,如果有人有更好的头衔,请告诉我。

编辑:我有点惊讶,下面的内容并不起作用。

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

我知道如何让for-loop做我想做的事情,但找到一个以熊猫为动力的做事方式会很不错。

2 个答案:

答案 0 :(得分:1)

我无法想出一些优雅的解决方案,但是通过循环数据框就可以得到一个残酷的力量,希望如果你的数据集不是很大,那将会有效:

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})

等待有人提出更优雅的解决方案。

答案 1 :(得分:1)

考虑将resample聚合为30分钟,然后运行nunique。然后运行transform以每24小时有条件地聚合新的唯一计数列。您需要先将时间戳设置为重新采样的索引,然后再将其设置为常规列以聚合为24小时。

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