You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Pandas中按用户组计算最近两次登录时间差

计算用户最近两次登录时间差的可行方案

先做数据预处理

首先必须把登录时间列转为pandas的datetime类型,否则无法进行时间运算:

import pandas as pd

# 构造示例数据(实际可替换为读取你的数据源)
data = {
    '用户': [34,34,34,34,34,37,37,37,38],
    '登录时间': ['2024-07-10 07:49:11.773', '2024-07-10 07:52:11.606', '2024-07-11 08:49:11.947', '2024-07-11 09:49:11.758', '2024-07-12 09:46:11.758', '2024-07-10 08:46:11.587', '2024-07-10 08:49:11.356', '2024-07-09 08:49:11.744', '2024-07-10 08:55:11.742']
}
df = pd.DataFrame(data)

# 转换时间格式
df['登录时间'] = pd.to_datetime(df['登录时间'])

方案一:分组+自定义函数(直观易维护)

这种方式逻辑清晰,适合数据量不大的场景:

def get_last_login_diff(group):
    # 按登录时间倒序,取最近的两次记录
    sorted_records = group.sort_values('登录时间', ascending=False)
    if len(sorted_records) >= 2:
        time_diff = sorted_records.iloc[0]['登录时间'] - sorted_records.iloc[1]['登录时间']
        # 格式化输出,优先显示天数,否则显示分钟
        if time_diff.days > 0:
            return f"{time_diff.days} day" if time_diff.days == 1 else f"{time_diff.days} days"
        else:
            total_minutes = int(time_diff.total_seconds() // 60)
            return f"{total_minutes} minute" if total_minutes == 1 else f"{total_minutes} minutes"
    # 只有一次登录的情况返回na
    return 'na'

# 分组应用函数,生成结果
result = df.groupby('用户').apply(get_last_login_diff).reset_index(name='登录时间差')

方案二:分组+shift(高性能)

如果你的数据集很大,用shift效率更高,避免自定义函数的开销:

# 先按用户分组,登录时间倒序排序
df_sorted = df.sort_values(['用户', '登录时间'], ascending=[True, False])

# 组内偏移一行,获取每个用户的上一次登录时间
df_sorted['prev_login'] = df_sorted.groupby('用户')['登录时间'].shift(1)

# 计算时间差,仅保留有两次登录的用户记录
df_sorted['time_diff'] = df_sorted.apply(
    lambda x: x['登录时间'] - x['prev_login'] if pd.notna(x['prev_login']) else pd.NA,
    axis=1
)

# 格式化时间差,并提取每个用户的第一条结果
valid_diff = df_sorted.dropna(subset=['time_diff']).groupby('用户').first().reset_index()
valid_diff['登录时间差'] = valid_diff['time_diff'].apply(
    lambda x: f"{x.days} day" if x.days > 0 else f"{int(x.total_seconds()//60)} minutes"
)

# 补充只有一次登录的用户
single_login_users = df.groupby('用户').filter(lambda g: len(g) == 1)['用户'].unique()
single_records = pd.DataFrame({'用户': single_login_users, '登录时间差': 'na'})

# 合并最终结果
result = pd.concat([valid_diff[['用户', '登录时间差']], single_records]).sort_values('用户').reset_index(drop=True)

你的原代码问题分析

你用的df.groupby('User')['logints'].nlargest(2).diff()之所以不稳定,是因为nlargest(2)返回的是带多级索引的Series(用户+原数据索引),此时调用diff()会跨用户计算差值,而不是在单个用户组内计算,导致结果不符合预期。必须确保差值计算是在每个用户组内部完成。

最终输出结果

运行上述任意方案,都会得到你期望的结果:

用户登录时间差
341 day
373 minutes
38na

内容的提问来源于stack exchange,提问作者ByRequest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:54:49