旋转分组方式(月和小时)日期时间列

时间:2018-08-27 10:33:08

标签: python pandas pivot-table

将DateTimeC列转换为日期时间类型(例如:

)后,我有了一个dataframe,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           

但是,我想在结果系列上使用ivot_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     

那么,对应于 由于日期和时间在同一列中,所以使用了数据透视表():DateTimeC

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

 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         

2 个答案:

答案 0 :(得分: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]

然后使用renamemean创建字典:

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

编辑:如果要将月份数转换为小数,请使用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

答案 1 :(得分:0)

如何像这样使用.unstack.reindex.fillna

(df.groupby([df.DateTimeC.dt.month, df.DateTimeC.dt.hour]).size()
 .unstack(1)
 .reindex(labels=np.arange(24), axis=1)
 .fillna(0))