Это пример моего набора данных об онлайн-играх. У нас есть идентификатор сеанса, который квалифицирует ставку, дата, когда произошла ставка, и результат ставки (win-draw-lost):
e = {'session': ['1', '3', '1', '1', '3', '1', '2', '2', '1', '3', '3', '3', '3', '3', '2', '3', '3'],
'date': ['2018-01-01 00:17:05', '2018-01-01 00:30:35', '2018-01-01 00:19:05', '2018-01-03 00:55:22',
'2018-01-01 00:21:07', '2018-01-01 00:22:09', '2018-02-01 00:35:22',
'2018-01-01 00:22:17', '2018-01-01 00:25:11', '2018-01-01 00:27:28', '2018-01-01 00:29:29',
'2018-01-01 00:25:09', '2018-01-01 00:17:01', '2018-02-01 00:31:16',
'2018-02-01 00:38:20', '2018-02-01 00:55:15', '2018-02-01 00:38:16'],
'status': ['win', 'loss', 'loss', 'draw', 'loss', 'win', 'loss', 'loss', 'win', 'draw', 'loss', 'loss', 'loss',
'win', 'draw', 'loss', 'loss']}
#create dataframe
df2 = pd.DataFrame(data=e)
#sort it by session and date
df2 = df2.sort_values(['session', 'date']).reset_index(drop=True)
df.head()
session date status
0 1 2018-01-01 00:17:05 win
1 1 2018-01-01 00:19:05 loss
2 1 2018-01-01 00:22:09 win
3 1 2018-01-01 00:25:11 win
4 1 2018-01-03 00:55:22 draw
Моя цель - подсчитать для каждой сессии максимальное количество сыгранных игр без выигрыша. Это то, что я сделал, следуя совету этого ТАК сообщения :
1. Сначала я создал столбец, в котором win = 1 , а остальные значения = 0
.
m = {'win':1, 'loss':0, 'draw':0}
df2['status_num'] = df2.status.map(m)
session date status status_num
0 1 2018-01-01 00:17:05 win 1
1 1 2018-01-01 00:19:05 loss 0
2 1 2018-01-01 00:22:09 win 1
3 1 2018-01-01 00:25:11 win 1
4 1 2018-01-03 00:55:22 draw 0
2. Для каждой сессии я вычисляю дни с момента последнего выигрыша , а затем добавляю результат в новый фрейм данных:
#create list of sessions
plist = list(df2.session.unique())
final = pd.DataFrame()
for i in plist:
#slice the dataset by session
sess = df2.loc[df2['session'] == i]
#calculate the last win occurrence
sess['Last_win']= sess.groupby(sess.status_num.cumsum()).cumcount()
#append the result
final = final.append(sess)
final
session date status status_num Last_win
0 1 2018-01-01 00:17:05 win 1 0
1 1 2018-01-01 00:19:05 loss 0 1
2 1 2018-01-01 00:22:09 win 1 0
3 1 2018-01-01 00:25:11 win 1 0
4 1 2018-01-03 00:55:22 draw 0 1
3. Наконец, я группируюсь, чтобы получить максимальную последовательность без какого-либо выигрышного события за сессию :
last_win = final.groupby('session')['Last_win'].max().reset_index()
last_win
session Last_win
0 1 1
1 2 2
2 3 5
Код делает то, что мне было нужно, НО он не очень производительный, и, поскольку у меня большой набор данных, я хотел бы найти лучшее решение с точки зрения времени выполнения.
я совершенно уверен, что узким местом является цикл for, и тот факт, что для каждой итерации я делаю групповую работу, но на самом деле я не могу придумать другой путь.
Я также попробовал подход, предложенный здесь , но мне не интересны дни.