如何基于最大日期获取每个唯一Campaign的最新状态与d_cap值
获取每个Campaign的最新记录(基于最大日期)
原始数据集
date campaign status d_cap 2019-10-07 campaign_1 start 400 2019-10-13 campaign_2 start 400 2019-10-14 campaign_1 change 1000 2019-10-14 campaign_2 change 800 2019-11-10 campaign_1 stop 0 2019-11-12 campaign_2 change 2000
期望输出
date campaign status d_cap 2019-11-10 campaign_1 stop 0 2019-11-12 campaign_2 change 2000
这个需求很常见,用pandas的内置方法完全可以高效解决,根本不用写for loop,给你两种简洁又高效的方案:
方案一:用groupby + idxmax定位最新记录
这种方法直接找到每个campaign对应最大日期的行索引,再提取对应数据,逻辑清晰高效:
import pandas as pd # 构造原始数据(如果你的数据已经是DataFrame,这步可以跳过) data = { 'date': ['2019-10-07', '2019-10-13', '2019-10-14', '2019-10-14', '2019-11-10', '2019-11-12'], 'campaign': ['campaign_1', 'campaign_2', 'campaign_1', 'campaign_2', 'campaign_1', 'campaign_2'], 'status': ['start', 'start', 'change', 'change', 'stop', 'change'], 'd_cap': [400, 400, 1000, 800, 0, 2000] } df = pd.DataFrame(data) # 先把date列转换成datetime类型,确保日期能正确比较大小 df['date'] = pd.to_datetime(df['date']) # 按campaign分组,找到每组中date最大的行的索引 max_date_indices = df.groupby('campaign')['date'].idxmax() # 根据索引筛选出最终结果 result = df.loc[max_date_indices].reset_index(drop=True) print(result)
方案二:排序后去重,更直观简洁
这种方法先按campaign分组、date降序排序,然后保留每个campaign的第一行,代码更短:
import pandas as pd data = { 'date': ['2019-10-07', '2019-10-13', '2019-10-14', '2019-10-14', '2019-11-10', '2019-11-12'], 'campaign': ['campaign_1', 'campaign_2', 'campaign_1', 'campaign_2', 'campaign_1', 'campaign_2'], 'status': ['start', 'start', 'change', 'change', 'stop', 'change'], 'd_cap': [400, 400, 1000, 800, 0, 2000] } df = pd.DataFrame(data) df['date'] = pd.to_datetime(df['date']) # 按campaign升序、date降序排序,然后保留每个campaign的第一条记录 result = df.sort_values(by=['campaign', 'date'], ascending=[True, False]) \ .drop_duplicates(subset='campaign', keep='first') \ .reset_index(drop=True) print(result)
两种方案都是向量化操作,比for loop效率高得多,尤其是当数据集很大的时候,优势会非常明显。
内容的提问来源于stack exchange,提问作者Sergey Grytsuk
相关产品推荐
相关产品推荐

