如何为每个ID删除DataFrame中指定URL之后的所有行?
解决方案
方法一:自定义函数 + 分组处理
逻辑直观,容易理解,适合小数据量场景:
import pandas as pd # 构造示例数据 df = pd.DataFrame({ 'id': [25,25,25,144,144,144,992,992,992], 'url': [ 'google.com/main', 'google.com/buy', 'google.com/videos', 'google.com/buy', 'google.com/videos', 'google.com/pictures', 'google.com/main', 'google.com/buy', 'google.com/videos' ] }) # 定义处理单组的函数:保留到第一个"google.com/buy"的所有行 def keep_until_buy(group): # 找到组内第一个目标url的索引 first_buy_idx = group[group['url'] == 'google.com/buy'].index.min() # 如果存在目标url,返回从开头到该索引的行;否则返回原组 if pd.notna(first_buy_idx): return group.loc[:first_buy_idx] return group # 按id分组应用函数,合并结果 result = df.groupby('id', group_keys=False).apply(keep_until_buy) print(result)
方法二:向量化操作(高效)
避免循环,用Pandas向量化API处理,适合大数据量:
import pandas as pd df = pd.DataFrame({ 'id': [25,25,25,144,144,144,992,992,992], 'url': [ 'google.com/main', 'google.com/buy', 'google.com/videos', 'google.com/buy', 'google.com/videos', 'google.com/pictures', 'google.com/main', 'google.com/buy', 'google.com/videos' ] }) # 生成掩码:标记所有非目标url的行,反向累计乘积后反转,得到目标url及之前的有效行 mask = df['url'] != 'google.com/buy' mask = mask[::-1].groupby(df['id']).cumprod()[::-1].astype(bool) # 合并目标url的行(上面的掩码会把目标url标记为False,需手动保留) result = df[mask | (df['url'] == 'google.com/buy')] print(result)
两种方法运行后都会得到期望结果:
id url 0 25 google.com/main 1 25 google.com/buy 3 144 google.com/buy 6 992 google.com/main 7 992 google.com/buy
内容的提问来源于stack exchange,提问作者Stepan P.
相关产品推荐
相关产品推荐

