我最近下载了英雄联盟数据。我有以下DF
df = pd.DataFrame.from_dict({'DateTime': {
0: 156102273400,
1: 156101627200,
2: 156092208200,
3: 1559897767000,
4: 1559890046000,
5: 1559889968000},
'EventType': {
0: 'LOGOUT_USER',
1: 'LOGIN',
2: 'LOGOUT_USER',
3: 'LOGIN',
4: 'LOGIN',
5: 'LOGIN'}})
我得到以下df:
>>>df
Index DateTime EventType
0 156102273400 LOGOUT_USER
1 156101627200 LOGIN
2 156092208200 LOGOUT_USER
3 1559897767000 LOGIN
4 1559890046000 LOGIN
5 1559889968000 LOGIN
我想在遇到下一个LOGOUT_USER
之前将一个LOGIN
映射到最小的LOGOUT_USER
。从那里我应该能够计算出总播放时间。
理想的输出如下:
>>>fixed_df
Index DateTime EventType
0 156102273400 LOGOUT_USER
1 156101627200 LOGIN
2 156092208200 LOGOUT_USER
3 1559889968000 LOGIN
答案 0 :(得分:3)
您可以
df.groupby(df.eventType.eq('LOGOUT_USER').cumsum()).agg(['first','last'])\
.stack(level=1).reset_index(drop=True)
Out[634]:
dateTime eventType
0 156102273400 LOGOUT_USER
1 156101627200 LOGIN
2 156092208200 LOGOUT_USER
3 1559889968000 LOGIN
答案 1 :(得分:3)
我认为您正在寻找groupby
和idxmin
。
grouper = df['EventType'].ne(df['EventType'].shift()).cumsum()
df.loc[df.groupby(grouper)['DateTime'].idxmin()]
DateTime EventType
0 156102273400 LOGOUT_USER
1 156101627200 LOGIN
2 156092208200 LOGOUT_USER
5 1559889968000 LOGIN
答案 2 :(得分:0)
没有groupby,您可以结合自己的逻辑:
# logouts
log_out = df.eventType.eq('LOGOUT_USER')
# before login
next_log_in = df.eventType.shift(-1).eq('LOGIN')
# logout followed by login
markers = log_out & next_log_in
# those logouts and logins after
df[markers | markers.shift()]
输出:
dateTime eventType
0 156102273400 LOGOUT_USER
1 156101627200 LOGIN
2 156092208200 LOGOUT_USER
3 1559897767000 LOGIN
答案 3 :(得分:0)
您还可以设置额外的组标签g
(加上EventType
),然后在不运行groupby
的情况下进行drop_duplicates:
df.assign(g=df['EventType'].eq('LOGOUT_USER').cumsum()) \
.drop_duplicates(['g','EventType'], keep='last') \
.drop('g', axis=1)
# DateTime EventType
#0 156102273400 LOGOUT_USER
#1 156101627200 LOGIN
#2 156092208200 LOGOUT_USER
#5 1559889968000 LOGIN