Решение, предложенное DYZ , производит данные только за «настоящие» месяцы.
Но рассмотрим исходные данные следующим образом:
df = pd.DataFrame(data=[
[ 1, 2018, 'A', '01' ], [ 1, 2018, 'A', '02' ], [ 2, 2018, 'B', '03' ],
[ 4, 2018, 'A', '04' ], [ 4, 2018, 'A', '05' ], [ 7, 2018, 'A', '06' ],
[ 7, 2018, 'B', '07' ], [ 7, 2018, 'B', '08' ] ],
columns=['Month', 'Year', 'Event', 'UniqueID'])
, где нет данныхза март, май и июнь, поэтому результат, напечатанный в соответствии с DYZ , будет иметь «пробелы».
Обратите внимание, что такая деталь, касающаяся «пробелов», является исходными данными:
- Для некоторых типов событий вы можете иметь «отсутствующие» данные также для первый и / или последний месяц.
- Но, тем не менее, по крайней мере, на мой взглядсреднее значение true должно быть рассчитано как сумма событий определенного типа, деленная на количество месяцев всей активности , а не на промежуток месяцев текущая активность.
Например, в моей выборке данных, если первое событие было в январе, а последнее в июле независимо от типа события , то вся операциязаняло 7 месяцев.
Так что одним из шагов должно быть вычисление MonthNo
- числа мес.тыс. целых действий.
Другое предложение состоит в том, чтобы «переключиться» с отдельных Год / Месяц столбцы на Дата (DateTime) и установите его в качестве индекса.Этот столбец (на самом деле индекс) понадобится в какой-то момент (см. Ниже).
Итак, мое предложение по написанию сценария таково:
import pandas as pd
import math
# Source data
df = pd.DataFrame(data=[ [ 1, 2018, 'A', '01' ], [ 1, 2018, 'A', '02' ],
[ 2, 2018, 'B', '03' ], [ 4, 2018, 'A', '04' ], [ 4, 2018, 'A', '05' ],
[ 7, 2018, 'A', '06' ], [ 7, 2018, 'B', '07' ], [ 7, 2018, 'B', '08' ] ],
columns=['Month', 'Year', 'Event', 'UniqueID'])
# Count of Events
df2 = df.groupby(['Year','Month','Event'])['Event'].size()\
.rename('Count of Events').reset_index()
# Replace Year / Month with Dat
df2['Dat'] = pd.to_datetime(df2.Year * 10000 + df2.Month * 100 + 1,
format='%Y%m%d')
df2.drop(columns=['Year', 'Month'], inplace=True)
df2.set_index('Dat', inplace=True)
# How many months took the activity
MonthNo = math.ceil((df2.index.max() - df2.index.min())/np.timedelta64(1, 'M')) + 1
Затем, если вы хотите иметь строкис нулевым количеством событий для «промежутков» месяцев, вызовите resample
для каждого типа события (здесь нужен индекс DateTime):
df3 = df2.groupby(['Event']).resample('MS').sum()
Результат:
Count of Events
Event Dat
A 2018-01-01 2
2018-02-01 0
2018-03-01 0
2018-04-01 2
2018-05-01 0
2018-06-01 0
2018-07-01 1
B 2018-02-01 1
2018-03-01 0
2018-04-01 0
2018-05-01 0
2018-06-01 0
2018-07-01 2
И чтобы вычислить среднее число событий каждого типа в месяц для всей деятельности , позвоните:
df3.groupby(level=0).sum() / MonthNo
и получите:
Count of Events
Event
A 0.714286
B 0.428571
Обратите внимание, что resample было необходимо только для того, чтобы получить месяцы без пробелов, а не вычислять средние числа.