基于多日出现情况为Pandas数据框分配趋势类型
为Pandas数据框添加趋势类型列
原始数据
首先定义目标数据框:
import pandas as pd df = pd.DataFrame({ "Value": ["A", "B", "C", "D", "A", "D", "A", "B"], "Day": ["2023-06-12", "2023-06-12", "2023-06-12", "2023-06-12", "2023-06-13", "2023-06-13", "2023-06-14", "2023-06-14"] })
趋势判定规则
- Trend:Value连续出现3天(如A)
- Sporadic:Value出现2天但非连续(如B)
- Anomaly:Value仅出现1次(如C)
- Becoming a trend:Value连续出现2天(如D)
解决方案
步骤1:转换日期格式
将Day列转为datetime类型,确保日期计算准确:
df['Day'] = pd.to_datetime(df['Day'])
步骤2:统计每个Value的关键指标
按Value分组,计算去重后的出现天数、日期范围,并判断是否连续:
value_stats = df.groupby('Value').agg( total_days=('Day', 'nunique'), # 去重后的实际出现天数 min_day=('Day', 'min'), # 首次出现日期 max_day=('Day', 'max') # 末次出现日期 ).reset_index() # 计算若日期连续时应有的总天数 value_stats['max_continuous_days'] = (value_stats['max_day'] - value_stats['min_day']).dt.days + 1 # 判断是否连续:实际天数等于连续天数则为连续 value_stats['is_continuous'] = value_stats['total_days'] == value_stats['max_continuous_days']
步骤3:映射趋势类型
根据规则为每个Value分配对应的趋势类型:
def assign_trend(row): if row['total_days'] == 1: return 'Anomaly' elif row['total_days'] == 3 and row['is_continuous']: return 'Trend' elif row['total_days'] == 2: return 'Becoming a trend' if row['is_continuous'] else 'Sporadic' return 'Unknown' # 处理未覆盖的特殊情况 value_stats['Trend Type'] = value_stats.apply(assign_trend, axis=1)
步骤4:合并结果到原数据
将趋势类型合并回原数据框,并恢复原始排序:
result_df = df.merge(value_stats[['Value', 'Trend Type']], on='Value', how='left') result_df = result_df.sort_values('Day').reset_index(drop=True)
最终结果
打印输出结果:
print(result_df.to_string(index=False))
输出内容如下:
Day Value Trend Type 2023-06-12 A Trend 2023-06-12 B Sporadic 2023-06-12 C Anomaly 2023-06-12 D Becoming a trend 2023-06-13 A Trend 2023-06-13 D Becoming a trend 2023-06-14 A Trend 2023-06-14 B Sporadic
内容的提问来源于stack exchange,提问作者Kusanagi
相关产品推荐
相关产品推荐

