【问题标题】:Pandas timeseries data - counting unique values during past 24 hours every 30 minutesPandas 时间序列数据 - 每 30 分钟计算过去 24 小时内的唯一值
【发布时间】:2017-11-12 03:10:26
【问题描述】:

我正在尝试根据每条消息的数据来衡量论坛上的消息活动。

为此,我想知道有多少独特/不同作者在过去 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 小时内至少发布了 3 次;该人仅将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,根据数据,在过去 24 小时内有 12 个不同的人发布了消息。

我尝试了pd.Timestamp.ceilgroupbyrolling 的不同组合,但都没有达到我想要的效果。有经验的人可能知道要做的事情的正确组合。

另外,如果有人有更好的标题想法,请告诉我。


编辑:我有点惊讶像下面这样的东西不起作用。

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

我知道如何使用 for 循环来做我想做的事,但如果能找到一种由 pandas 驱动的做事方式,那就太好了。

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

    • 这是朝着正确方向迈出的一步,但是如果作者在前一天以多个 30 分钟的间隔发帖,则此代码仍会计算同一作者的多个帖子。例如,同一作者可能在 14:30、15:00、15:30 等时间发帖,导致每个相应的“消息作者”计数 +1,总和为 3,而不是 1; 24-HourCount 不能是每 30 分钟内唯一作者的总和。
    • 查看运行 24 小时滚动唯一 消息作者 唯一计数的更新,然后重新采样到 30 分钟。间隔。数据使用发布的示例。
    • 这得到了 30 分钟时间箱的正确答案,其中至少有 一个 消息,但不幸的是它为所有其他人提供了NaNs。更正是将 transform 函数应用于跨越整个时间的 30 分钟日期范围。然后你不需要重新采样任何东西。不幸的是,对于“1D”,它每秒只能执行大约 50 行。感谢您展示这些出色的功能。
    【解决方案2】:

    我无法想出一些优雅的解决方案,但是通过循环遍历数据框是一种残酷的解决方案,希望如果您的数据集不是很大,这将起作用:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多