用相同的值填充列,但组中的第一行除外

时间:2018-08-04 19:21:05

标签: python pandas

我有一个df:

import pandas as pd
df = pd.DataFrame({'user_id': [1,1,2,1,2,1,2,3], 'movie_id': ['35','120','898','546','989','42','546','35'], 
'time':['1.7','2.1','1.3','2.4','1.4','7.0','2.1','1.1']})

看起来像这样:

user_id  movie_id  time
1          35      1,7
1         120      2.1
2         898      1.3
1         546      2.4
2         989      1.4
1         42       7.0
2         546      2.1
3         35.      1.1

我的目标是按user_id分组,按时间排序,并用“ 1”填充新列,但每个组中的第一行除外-“时间”列显示自上次点击以来经过的秒数。 最终,我应该获得这样的输出,其中包含用户在活动电影之前评分的最后一部电影的指示器:

user_id  movie_id  time  last_rated
1          35      1.7      0
1         120      2.1      1
2         898      1.3      0
1         546      2.4      1
2         989      1.4      1
1         42       7.0      1
2         546      2.1      1
3         35       1.1      0

我已经尝试了group_by,shift,cumsum,但仍然无法获得所需的输出。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

可以使用cumcount()np.where()

df['last_rated'] = np.where(df.groupby('user_id').cumcount() == 0, 0, 1)

或(按照下面的@coldspeed)

df.groupby('user_id').cumcount().astype(bool).astype(int)

输出

    user_id   movie_id  time    last_rated
0   1         35          1.7   0
1   1         120         2.1   1
2   2         898         1.3   0
3   1         546         2.4   1
4   2         989         1.4   1
5   1         42          7.0   1
6   2         546         2.1   1
7   3         35          1.1   0

您可以预先使用sort_values来确保您拥有正确的分类条件。但是,如果您想保持df不变,可以在组内进行排序:

g = df.groupby('user_id', as_index=False).apply(lambda x: x.sort_values(by='time')).groupby('user_id').cumcount().reset_index(level=0,drop=True)

df['l'] = (g/g).fillna(0)

答案 1 :(得分:1)

您可以将GroupBytransform一起使用minuser_id,以df['time']计算一系列最小值。然后针对bool检查是否相等,并将int转换为g = df.groupby('user_id')['time'].transform('min') df['last_rated'] = (df['time'] != g).astype(int)

time

假设您的数据框已经按user_id的顺序对每个GroupBy进行了排序,则可以更有效地将'first'g = df.groupby('user_id')['time'].transform('first') 一起使用:

print(df)

   user_id movie_id time  last_rated
0        1       35  1.7           0
1        1      120  2.1           1
2        2      898  1.3           0
3        1      546  2.4           1
4        2      989  1.4           1
5        1       42  7.0           1
6        2      546  2.1           1
7        3       35  1.1           0

结果:

{{1}}