R语言日期处理:统计预警次数及预警时长
水质监测预警统计方案
一、Excel实现步骤
1. 数据预处理
- 将数据按采样地点和采样日期升序排序(通过「数据→排序」功能,主关键字选采样地点,次关键字选采样日期)。
2. 添加辅助列标记预警周期
- 预警状态列(D列):输入公式
=IF(C2>104,1,0),用1标记触发预警的样本,0标记正常样本。 - 预警组列(E列):输入公式
=IF(AND(D2=1,D1=0),MAX(E$1:E1)+1,IF(D2=1,E1,0)),自动为连续的预警周期分配唯一组号(正常样本组号为0)。
3. 统计总预警次数
- 插入数据透视表,行区域拖入「采样地点」,值区域拖入「预警组」,将值字段设置为「计数」,并筛选掉组号为0的记录,即可得到每个地点的总预警次数。
4. 计算单次预警平均时长
- 预警结束日期列(F列):输入公式
=IF(D2=1,MINIFS(B$2:B$100,A$2:A$100,A2,D$2:D$100,0,B$2:B$100,">"&B2), ""),自动获取当前预警周期后第一个正常样本的日期。 - 预警时长列(G列):输入公式
=IF(E2>1,F2-B2, ""),计算单次预警的持续天数(符合“截止到但不包含达标日期”的要求)。 - 再次插入数据透视表,行区域拖入「采样地点」,值区域拖入「预警时长」并设置为「平均值」,筛选掉空白值后得到单次预警平均时长。
二、Python(Pandas)实现代码
import pandas as pd # 读取数据(根据实际文件格式调整,示例为csv) df = pd.read_csv("水质监测数据.csv") # 转换采样日期为日期格式 df["采样日期"] = pd.to_datetime(df["采样日期"]) # 按采样地点和日期排序 df = df.sort_values(by=["采样地点", "采样日期"]) # 标记预警状态 df["预警状态"] = df["检测结果"].map(lambda x: 1 if x > 104 else 0) # 为连续预警周期分配唯一组号 df["预警组"] = df.groupby("采样地点")["预警状态"].apply( lambda x: (x != x.shift()).cumsum() * x ) # 计算每个预警组的时长 def calc_warn_duration(group): warn_records = group[group["预警组"] != 0] if len(warn_records) == 0: return pd.DataFrame() # 提取每个预警组的开始日期 start_dates = warn_records.groupby("预警组")["采样日期"].min().reset_index() # 获取每个预警组对应的结束日期(之后第一个正常样本日期) end_dates = [] for gid in start_dates["预警组"]: last_warn_day = warn_records[warn_records["预警组"] == gid]["采样日期"].max() next_normal = group[(group["采样日期"] > last_warn_day) & (group["预警状态"] == 0)]["采样日期"].min() end_dates.append(next_normal) start_dates["预警结束日期"] = end_dates start_dates["预警时长"] = (start_dates["预警结束日期"] - start_dates["采样日期"]).dt.days start_dates["采样地点"] = group["采样地点"].iloc[0] return start_dates[["采样地点", "预警组", "预警时长"]] # 生成各采样点的预警明细 warn_details = df.groupby("采样地点").apply(calc_warn_duration).reset_index(drop=True) # 统计最终结果 final_result = warn_details.groupby("采样地点").agg( 总预警次数=("预警组", "nunique"), 单次平均预警时长=("预警时长", "mean") ).reset_index() print(final_result)
内容的提问来源于stack exchange,提问作者Johanna
相关产品推荐
相关产品推荐

