【问题标题】:Pivoting a groupby (month and hour ) datetime column透视 groupby (月和小时)日期时间列
【发布时间】:2018-08-27 10:33:08
【问题描述】:

在将 DateTimeC 列转换为日期时间类型后,我有一个数据框,df,例如:

  Index     DateTimeC                       eventName  
    0      2017-08-20 01:11:24.210000        ABC           
    1      2017-08-20 01:11:30.224000        CDE         
    2      2017-08-20 02:16:30.210000        CDE       
    3      2017-08-20 02:27:30.211000        CDE       
    2      2017-09-10 01:30:40.212000        DEF            
    3      2017-09-11 01:35:23.122000        CDE            
    4      2017-09-11 02:22:22.145000        CDE            
    5      2017-09-16 02:26:11.222000        DEF           

我打算按月和小时分组,并计算分组对象中 eventName 中的事件数。所以应用此代码:

 df2=df.groupby([df['DateTimeC'].dt.month,df['DateTimeC'].dt.hour])['EventName'].count()

我明白了:

   Index   EventName                       
    8,1     2          
    8,2     2         
    9,1     2           
    9,2     2           

但是,我想将结果系列上的 pivot_table () 用作索引,将小时用作列,而 value 参数应该是频率。所以生成的数据框应该是:

   Index    0  1  2  3  4  5  6  7  8... 24                
    8       0  2  2  0  0  0  0  0  0... 0
    9       0  2  2  0  0  0  0  0  0... 0     

那么对应的参数是什么 pivot_table() 因为日期和时间在同一列:DateTimeC

我尝试添加 rename_index 来重命名频率/计数结果的列,这样我就可以使用以下代码将新名称传递给 pivot_table () 中的“值”参数:

 df2=df.groupby([df['DateTimeC'].dt.month,df['DateTimeC'].dt.hour])['EventName'].count().reset_index(name='frequency')

但我收到此错误:

ValueError: cannot insert DateTimeC, already exists

此外,获取每个月每小时的平均值,并将与特定月份关联的数字转换为对应的单词

    Index      averagePerHour                       
    August       0.17          
    September    0.17         

【问题讨论】:

    标签: python pandas pivot-table


    【解决方案1】:

    我认为需要unstack 进行整形,如有必要,需要reindex 添加缺失的时间:

    df2=(df.groupby([df['DateTimeC'].dt.month.rename('month'),
                    df['DateTimeC'].dt.hour.rename('hour')])
          .size()
          .unstack(fill_value=0)
          .reindex(columns=np.arange(24), fill_value=0))
    print (df2)
    hour   0   1   2   3   4   5   6   7   8   9  ...  14  15  16  17  18  19  20  \
    month                                         ...                               
    8       0   2   2   0   0   0   0   0   0   0 ...   0   0   0   0   0   0   0   
    9       0   2   2   0   0   0   0   0   0   0 ...   0   0   0   0   0   0   0   
    
    hour   21  22  23  
    month              
    8       0   0   0  
    9       0   0   0  
    
    [2 rows x 24 columns]
    

    然后为rename和mean创建字典:

    L = ['Jan', 'Feb', 'Mar', 'Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    d = dict(enumerate(L, 1))
    df3 = df2.mean(axis=1).rename(d).to_frame('averagePerHour')
    print (df3)
           averagePerHour
    month                
    Aug          0.166667
    Sep          0.166667
    

    如果省略 reindex 并错过几个小时,则 mean 不同:

    df2=(df.groupby([df['DateTimeC'].dt.month.rename('month'),
                    df['DateTimeC'].dt.hour.rename('hour')])
          .size()
          .unstack(fill_value=0)
          )
    print (df2)
    hour   1  2
    month      
    8      2  2
    9      2  2
    
    L = ['Jan', 'Feb', 'Mar', 'Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    d = dict(enumerate(L, 1))
    df3 = df2.mean(axis=1).rename(d).to_frame('averagePerHour')
    print (df3)
           averagePerHour
    month                
    Aug               2.0
    Sep               2.0
    

    编辑:如果想将月份数转换为 stings,请使用 dt.strftime,同时检查 http://strftime.org/:

    df2=(df.groupby([df['DateTimeC'].dt.strftime('%B').rename('month'),
                    df['DateTimeC'].dt.hour.rename('hour')])
          .size()
          .unstack(fill_value=0)
          )
    print (df2)
    hour       1  2
    month          
    August     2  2
    September  2  2
    
    df3 = df2.mean(axis=1).to_frame('averagePerHour')
    print (df3)
               averagePerHour
    month                    
    August                2.0
    September             2.0
    

    【讨论】:

    • 谢谢伙计,它起作用了,但是为了得到平均值:我有没有可能得到一个更简单的方法,直接在月份列上使用 striptime() 将月份的数字转换为相应的单词,例如 ( 3 月至 3 月),并帮助使用 mean() 计算平均值
    • 我收到此错误:AttributeError: 'list' object has no attribute 'dt'
    • @Bode - 也许有些错字?我刚刚意识到需要%B 而不是%a,检查编辑的答案。
    • 好的!它现在可以工作了,谢谢,但月份不是按升序排列的……比如三月,四月,五月,六月。如何对月份进行排序?
    • @Bode - 我认为需要this 解决方案,只需将Jan 替换为January 和类似的月份
    猜你喜欢
    • 1970-01-01
    • 2017-08-09
    • 2014-03-12
    • 2017-04-14
    • 2022-01-20
    • 2021-11-17
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    相关资源
    最近更新 更多