代码之家  ›  专栏  ›  技术社区  ›  plalanne

给定日期时间列的pandas按周分组

  •  3
  • plalanne  · 技术社区  · 6 年前

    假设我有以下数据示例:

    df = pd.DataFrame({'date':['2011-01-01','2011-01-02',
                           '2011-01-03','2011-01-04','2011-01-05',
                           '2011-01-06','2011-01-07','2011-01-08',
                           '2011-01-09','2011-12-30','2011-12-31'],
                       'revenue':[5,3,2,
                                  10,12,2,
                                  1,0,6,10,12]})
    
    # Let's format the date and add the week number and year
    df['date'] = pd.to_datetime(df['date'],format='%Y-%m-%d')
    df['week_number'] = df['date'].dt.week
    df['year'] = df['date'].dt.year
    
    df
    
            date        revenue     week_of_year    year
    0       2011-01-01  5           52              2011
    1       2011-01-02  3           52              2011
    2       2011-01-03  2           1               2011
    3       2011-01-04  10          1               2011
    4       2011-01-05  12          1               2011
    5       2011-01-06  2           1               2011
    6       2011-01-07  1           1               2011
    7       2011-01-08  0           1               2011
    8       2011-01-09  6           1               2011
    9       2011-12-30  10          52              2011
    10      2011-12-31  12          52              2011
    

    我想计算每周的收入,以便以后绘制结果,并分析时间序列。然后,预期的产出将是这样的:

        week    revenue
    0   1       8
    1   2       33
    2   52      22
    

    我第一次想到用 timestamp.week 是的。
    但是,我不知道如何处理第1周之前的一周的iso周数定义。我有点困惑,因为按 week_number 在这种情况下,是年初收入和年末收入的总和。

    3 回复  |  直到 6 年前
        1
  •  5
  •   BENY    6 年前

    当您使用dt.week转换时,它是 ISO week date 是的。

    你可以使用 strftime

    df.groupby(df.date.dt.strftime('%W')).revenue.sum()
    Out[588]: 
    date
    00     8
    01    33
    52    22
    Name: revenue, dtype: int64
    
        2
  •  0
  •   rpanai    6 年前

    我认为在这种情况下你应该非常小心。如果你想拥有多年的每周收入,你可以考虑把前几天移到2010年的最后一周。

    import pandas as pd
    import numpy as np
    
    date =  pd.date_range(start="2011-01-01", end="2011-01-09")
    date = [str(d)[:10] for d in date] + ["2011-12-30", "2011-12-31"]
    rev =  np.random.randint(1,10, len(date))
    df =  pd.DataFrame({"date": date, "rev":rev})
    df["date"] =  df["date"].astype("M8[us]")
    
    df["week"] = df["date"].dt.week
    df["year"] = df["date"].dt.year
    df["year"] = np.where((df["week"]==52) & (df["date"].dt.month==1), 
                          df["year"]-1,
                          df["year"])
    
    df.groupby(["year", "week"])["rev"].sum()
    

    如果你乐意拥有第一个 0 你可以考虑用这个来代替

    df["week"] = np.where((df["week"]==52) & (df["date"].dt.month==1),
                          0, 
                          df["week"])
    
        3
  •  0
  •   Alex G    6 年前

    你可以用 date 列作为索引,然后对时间序列重新采样。

    df.index = pd.to_datetime(df['date'])
    df.resample('W').sum()
    

    有了这个解决方案你甚至不需要 week year 列。