У меня есть dataframe, df после преобразования столбца DateTimeC в тип datetime, например:
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() в результирующей серии как месяц, как индекс и час в качестве столбца, а параметр значения должен быть частотой. Таким образом, итоговый фреймворк должен быть:
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
Я думаю, что нужно 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
EDIT: если вы хотите, чтобы число месяцев в dt.strftime
, используйте 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
Как насчет использования .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))