如何在DataFrame中识别并删除daynumber差值为1的重复行
实现方法
核心逻辑
我们需要筛选出同一用户(name和age相同)下,两行daynumber差值为1,且至少有一个其他属性(att1/att2/att3)相同的行(对应示例中的john和david组)。
代码实现
首先构建示例DataFrame:
import pandas as pd data = { 'name': ['john', 'john', 'david', 'david', 'steve', 'steve', 'james', 'james'], 'age': [45, 45, 40, 40, 36, 36, 40, 40], 'daynumber': [1234, 1235, 1230, 1231, 1234, 1222, 1238, 1239], 'att1': [100, 100, 110, 100, 90, 90, 99, 89], 'att2': [103, 103, 113, 103, 107, 107, 106, 109], 'att3': [101, 101, 100, 100, 111, 111, 145, 90] } myDf = pd.DataFrame(data)
执行筛选逻辑:
# 按用户分组后,每组内按daynumber排序,保证相邻行是时间顺序的 grouped = myDf.groupby(['name', 'age']).apply(lambda x: x.sort_values('daynumber')).reset_index(drop=True) # 计算相邻行的daynumber差值绝对值 grouped['day_diff'] = grouped['daynumber'].diff().abs() # 判断当前行与上一行是否至少有一个属性(att1/att2/att3)相同 grouped['has_common_att'] = (grouped[['att1', 'att2', 'att3']] == grouped[['att1', 'att2', 'att3']].shift()).any(axis=1) # 标记符合条件的行:相邻行day差1且有共同属性,同时成对标记两行(因为符合条件的是一组两行) grouped['is_match'] = (grouped['day_diff'] == 1) & grouped['has_common_att'] grouped['is_match'] = grouped['is_match'] | grouped['is_match'].shift(-1).fillna(False) # 筛选结果并移除辅助列 result = grouped[grouped['is_match']].drop(columns=['day_diff', 'has_common_att', 'is_match']) print(result)
输出结果
运行后得到的结果与预期一致:
name age daynumber att1 att2 att3 0 john 45 1234 100 103 101 1 john 45 1235 100 103 101 2 david 40 1230 110 113 100 3 david 40 1231 100 103 100
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

