计算在熊猫数据框中以不同值交错的重复项

时间:2019-07-04 16:05:54

标签: pandas

这是我的数据的非常简化的版本:

    ╔═════════╤═══════════╗
    ║ user_id │ module_id ║
    ╠═════════╪═══════════╣
    ║ 1       │ 1         ║
    ╟─────────┼───────────╢
    ║ 1       │ 1         ║
    ╟─────────┼───────────╢
    ║ 1       │ 2         ║
    ╟─────────┼───────────╢
    ║ 1       │ 1         ║
    ╟─────────┼───────────╢
    ║ 2       │ 2         ║
    ╟─────────┼───────────╢
    ║ 2       │ 1         ║
    ╟─────────┼───────────╢
    ║ 2       │ 2         ║
    ╟─────────┼───────────╢
    ║ 2       │ 2         ║
    ╟─────────┼───────────╢
    ║ 2       │ 1         ║
    ╟─────────┼───────────╢
    ║ 2       │ 2         ║
    ╚═════════╧═══════════╝

这是我要添加的列:

    ╔═════════╤═══════════╤════════════════════╗
    ║ user_id │ module_id │ repeated_module_id ║
    ╠═════════╪═══════════╪════════════════════╣
    ║ 1       │ 1         │ NaN                ║
    ╟─────────┼───────────┼────────────────────╢
    ║ 1       │ 1         │ NaN                ║
    ╟─────────┼───────────┼────────────────────╢
    ║ 1       │ 2         │ NaN                ║
    ╟─────────┼───────────┼────────────────────╢
    ║ 1       │ 1         │ 1                  ║
    ╟─────────┼───────────┼────────────────────╢
    ║ 2       │ 2         │ NaN                ║
    ╟─────────┼───────────┼────────────────────╢
    ║ 2       │ 1         │ NaN                ║
    ╟─────────┼───────────┼────────────────────╢
    ║ 2       │ 2         │ 2                  ║
    ╟─────────┼───────────┼────────────────────╢
    ║ 2       │ 2         │ NaN                ║
    ╟─────────┼───────────┼────────────────────╢
    ║ 2       │ 1         │ 1                  ║
    ╟─────────┼───────────┼────────────────────╢
    ║ 2       │ 2         │ 2                  ║
    ╚═════════╧═══════════╧════════════════════╝

即如果用户之前(但不是紧接在此之前)完成了一个模块,则会重复该模块。

我想用矢量化的熊猫来实现这一点,但是我看不到如何开始。

2 个答案:

答案 0 :(得分:2)

IIUC,您可以尝试:

df=df.assign(repeated_module_id=df.loc[df.groupby('user_id')['module_id'].apply(lambda x:
        x.ne(x.shift())&x.duplicated()),'module_id'])

   user_id  module_id  repeated_module_id
0        1          1                 NaN
1        1          1                 NaN
2        1          2                 NaN
3        1          1                 1.0
4        2          2                 NaN
5        2          1                 NaN
6        2          2                 2.0
7        2          2                 NaN
8        2          1                 1.0
9        2          2                 2.0

答案 1 :(得分:2)

您可以在整个框架上使用duplicated来同时检查user_id module_id,您不需要groupby + { {1}}。然后,就像根据您的初始帧进行遮罩一样简单。

apply
m1 = df['module_id'].ne(df['module_id'].shift())
m2 = df.duplicated(['user_id', 'module_id'])

df['module_id'].where(m1 & m2)

这应该比0 NaN 1 NaN 2 NaN 3 1.0 4 NaN 5 NaN 6 2.0 7 NaN 8 1.0 9 2.0 Name: module_id, dtype: float64

快得多
apply