【问题标题】:Timestamp GroupBy pandasTimestamp GroupBy pandas
【发布时间】:2021-09-21 11:33:35
【问题描述】:

我正在尝试对时间序列数据集进行分组,以便我可以找到一周中最频繁的一天、一个月中的一周等。

我的数据集如下所示:

ID Date      
1  2020-01-02
1  2020-01-09
1  2020-01-08

我的输出数据集应该如下所示:

ID Pref_Day_Of_Week_A Pref_Week_Of_Month_A 
1  4                  2

(这里的星期四是星期几,第二周是给定日期的月份星期) 因此,本质上是试图找出每个 ID 的模式(最频繁)一周中的某一天和模式(最频繁)一周中的一周。知道如何在 Python 中实现这一点吗?数据集包含多个此类 ID,这只是 1 个此类 ID 的示例,数据集具有多个具有相似时间戳数据的 ID。

【问题讨论】:

    标签: python pandas numpy scipy


    【解决方案1】:

    GroupBy.agg 的命名聚合中使用Series.modeSeries.iat 选择第一模式的自定义lambda 函数:

    df = pd.DataFrame({"ID":[1,1,1,2,2,2],
                       "Date": ["2020-01-02", "2020-01-09", "2020-01-08"]*2})
    
    #https://stackoverflow.com/a/64192858/2901002
    def weekinmonth(dates):
        """Get week number in a month.
        
        Parameters: 
            dates (pd.Series): Series of dates.
        Returns: 
            pd.Series: Week number in a month.
        """
        firstday_in_month = dates - pd.to_timedelta(dates.dt.day - 1, unit='d')
        return (dates.dt.day-1 + firstday_in_month.dt.weekday) // 7 + 1
        
    
    df.Date = pd.to_datetime(df.Date)
    df['dayofweek'] = df.Date.dt.dayofweek
    df['week'] = weekinmonth(df['Date'])
    
    f = lambda x: x.mode().iat[0]
    df1 = (df.groupby('ID', as_index=False).agg(Pref_Day_Of_Week_A=('dayofweek',f), 
                                                Pref_Week_Of_Month_A=('week',f)))
    print (df1)
       ID  Pref_Day_Of_Week_A  Pref_Week_Of_Month_A
    0   1                   3                     2
    1   2                   3                     2
    

    【讨论】:

    • 这给出了一年中的一周,而不是一个月的一周。除此之外,它工作得很好
    • @sinha-shaurya - 你能检查thisdf['week'] =weekinmonth(df['Date']) 吗?
    【解决方案2】:

    您可以使用.groupby()ID 分组,然后使用带有命名聚合.agg() 进行聚合,为dayofweekweek 的2 个源列设置新列名。通过pd.Series.mode获取模式

    df = pd.DataFrame({"ID":[1,1,1,2,2,2],
                       "Date": ["2020-01-02", "2020-01-09", "2020-01-08", "2020-01-04", "2020-01-21", "2020-01-22"] })
    df.Date = pd.to_datetime(df.Date)
    df['dayofweek'] = df.Date.dt.dayofweek
    df['week'] = df.Date.dt.isocalendar().week
    
    df_out = (df.groupby('ID', as_index=False)[['dayofweek', 'week']]
                .agg(Pref_Day_Of_Week_A=('dayofweek', lambda x:  pd.Series.mode(x)[0]), 
                     Pref_Week_Of_Month_A=('week', lambda x:  pd.Series.mode(x)[0]))
             )
    

    结果:

    print(df_out)
    
       ID  Pref_Day_Of_Week_A  Pref_Week_Of_Month_A
    0   1                   3                     2
    1   2                   1                     4
    

    【讨论】:

      【解决方案3】:
      import pandas as pd
      df = pd.DataFrame({"ID":[1,1,1], "Date": ["2020-01-02", "2020-01-09", "2020-01-08"]})
      df.Date = pd.to_datetime(df.Date)
      df['dayofweek'] = df.Date.dt.dayofweek
      df['week'] = df.Date.dt.isocalendar().week
      df[['ID', 'dayofweek', 'week']].mode()
      

      输出:

         ID  dayofweek  week
      0   1          3     2
      

      PS:dayofweek 假设一周从星期一开始,用 0 表示,到星期日结束,用 6 表示。这使得星期四第 3 天

      【讨论】:

      • 我想我应该提到数据集包含多个 ID。所以在某些时候需要一个 groupby 操作
      • 用于按使用分组的模式:df[['ID', 'dayofweek', 'week']].groupby('ID').apply(pd.DataFrame.mode)
      • df=df.sort_values(by='Date') df2=df.groupby('ID').agg( MODE_DAY_OF_WEEK=('Date',lambda x: stats.mode(x.dt .dayofweek)[0])) 我试过这个。但是它是否正确?很难手动验证这一点(统计数据来自 scipy)
      猜你喜欢
      • 1970-01-01
      • 2015-05-13
      • 1970-01-01
      • 1970-01-01
      • 2016-12-05
      • 2022-01-02
      • 2017-04-06
      • 2017-03-16
      相关资源
      最近更新 更多