【问题标题】:How to do rolling window count on time series with multi-index?如何使用多索引对时间序列进行滚动窗口计数?
【发布时间】:2019-12-18 05:44:47
【问题描述】:

我有这个数据框:

ID      Date                          Received      
000     2018-01-01 00:00:00+00:00     True
        2018-01-01 06:24:44+00:00     True
        2018-01-03 16:24:45+00:00     False
        2018-01-13 20:00:00+00:00     True
        2018-01-13 23:00:00+00:00     True
        2018-01-25 22:30:55+00:00     True 
        2018-01-26 00:30:55+00:00     False

111     2018-01-01 12:00:00+00:00     True
        2018-01-02 15:00:45+00:00     True
        2018-01-04 00:00:00+00:00     True


有没有办法在 7 天内对 Received 列中的 True 值的数量进行滚动窗口计数并按 ID 分组?我尝试使用 df.rolling('7D').count() 但它返回错误。

我一直在寻找这样的东西:

ID      Date range                                                Count     
000     2018-01-01 00:00:00+00:00 - 2018-01-07 00:00:00+00:00     2
        2018-01-08 20:00:00+00:00 - 2018-01-14 00:00:00+00:00     2
        2018-01-15 22:30:55+00:00 - 2018-01-21 20:00:00+00:00     0
        2018-01-22 22:30:55+00:00 - 2018-01-28 20:00:00+00:00     1

111     2018-01-01 00:00:00+00:00 - 2018-01-07 00:00:00+00:00     3

【问题讨论】:

    标签: python pandas time-series rolling-computation


    【解决方案1】:

    你可以试试pd.Grouper并指定频率:

    df.groupby(["ID", pd.Grouper(key='Date', freq='1W')])["Received"].sum()
    

    完整答案:

    # Count the number of True per week per ID
    out = df.groupby(["ID", pd.Grouper(key='Date', freq='1W')])["Received"] \
            .sum() \
            .to_frame() \
            .reset_index() \
            .rename(columns={"Received": "Count"})
    print(out)
    #     ID                      Date  Count
    # 0  000 2018-01-07 00:00:00+00:00    2.0
    # 1  000 2018-01-14 00:00:00+00:00    2.0
    # 2  000 2018-01-28 00:00:00+00:00    1.0
    # 3  111 2018-01-07 00:00:00+00:00    3.0
    
    
    # Fill missing date ranges
    def fill_date_range(df):
        dates = pd.date_range(df.Date.min(), df.Date.max(), freq="1W")
        return df.set_index("Date") \
                 .reindex(dates)[['Count']] \
                 .fillna(0)
    
    # Fill missing date range             
    out = out.groupby(by="ID").apply(fill_date_range) \
            .reset_index()  \
            .rename(columns={"level_1": "Date"})
    print(out)
    #     ID                      Date  Count
    # 0  000 2018-01-07 00:00:00+00:00    2.0
    # 1  000 2018-01-14 00:00:00+00:00    2.0
    # 2  000 2018-01-21 00:00:00+00:00    0.0
    # 3  000 2018-01-28 00:00:00+00:00    1.0
    # 4  111 2018-01-07 00:00:00+00:00    3.0
    
    # Add date range interval as string
    format = '%Y-%m-%d %H:%M:%S'
    out["Date_expected"] = out.Date.dt.strftime(format) + " - " + (out.Date + pd.Timedelta(weeks=-1)).dt.strftime(format)
    print(out)
    #     ID                      Date  Count                              Date_expected
    # 0  000 2018-01-07 00:00:00+00:00    2.0  2018-01-07 00:00:00 - 2017-12-31 00:00:00
    # 1  000 2018-01-14 00:00:00+00:00    2.0  2018-01-14 00:00:00 - 2018-01-07 00:00:00
    # 2  000 2018-01-21 00:00:00+00:00    0.0  2018-01-21 00:00:00 - 2018-01-14 00:00:00
    # 3  000 2018-01-28 00:00:00+00:00    1.0  2018-01-28 00:00:00 - 2018-01-21 00:00:00
    # 4  111 2018-01-07 00:00:00+00:00    3.0  2018-01-07 00:00:00 - 2017-12-31 00:00:00
    

    【讨论】:

    • 对不起,我还有一个问题,有没有办法计算该范围内的所有值,包括 False 值?
    • 如有需要,请随时提出新问题。快乐编码:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-20
    • 2020-06-13
    • 2018-07-07
    • 2019-08-04
    • 2019-12-23
    • 2019-09-25
    相关资源
    最近更新 更多