在R中按连续年份分组并保留每组首次出现记录的实现方法
解决方案
针对按Org分组后,将连续Year值归为同一组并仅保留每组第一条记录的需求,以下是几种常用工具的实现方式:
SQL 实现
利用窗口函数LAG()计算当前行与上一行的年份差值,通过判断差值是否大于1来划分连续年份组,最后提取每个组的第一条记录:
WITH grouped_data AS ( SELECT Org, Year, Value, -- 标记连续年份组:当前年份与上一行年份差大于1时,组号递增 SUM(CASE WHEN Year - LAG(Year) OVER (PARTITION BY Org ORDER BY Year) > 1 THEN 1 ELSE 0 END) OVER (PARTITION BY Org ORDER BY Year) AS group_id FROM your_table ) SELECT Org, Year, Value FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Org, group_id ORDER BY Year) AS rn FROM grouped_data ) t WHERE rn = 1 ORDER BY Org, Year;
Pandas 实现
通过计算年份差值生成分组标识,再按分组提取第一条记录:
import pandas as pd # 示例数据(实际可替换为读取你的数据集) df = pd.DataFrame({ 'Org': ['A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B'], 'Year': [2011,2012,2013,2016,2017,2018,2019,2022,2007,2008,2009,2015,2016,2019,2021,2022], 'Value': [1,1,2,2,2,2,2,5,1,1,1,1,1,3,4,5] }) # 按Org分组,计算年份差值,生成连续年份组的标识 df['group_id'] = df.groupby('Org')['Year'].diff().fillna(1).gt(1).cumsum() # 提取每个Org+group_id分组的第一条记录 result = df.groupby(['Org', 'group_id']).first().reset_index(drop=True) # 输出结果 print(result[['Org', 'Year', 'Value']])
PySpark 实现
借助窗口函数实现连续年份分组,再筛选每组第一条记录:
from pyspark.sql import SparkSession from pyspark.sql.window import Window from pyspark.sql.functions import lag, sum, when, row_number # 初始化Spark会话 spark = SparkSession.builder.appName("continuous_year_group").getOrCreate() # 示例数据(实际可替换为读取你的数据集) data = [ ("A",2011,1),("A",2012,1),("A",2013,2),("A",2016,2), ("A",2017,2),("A",2018,2),("A",2019,2),("A",2022,5), ("B",2007,1),("B",2008,1),("B",2009,1),("B",2015,1), ("B",2016,1),("B",2019,3),("B",2021,4),("B",2022,5) ] df = spark.createDataFrame(data, ["Org", "Year", "Value"]) # 定义窗口:按Org分区,Year排序 window_part = Window.partitionBy("Org").orderBy("Year") # 计算当前年份与上一行的差值,生成组号 df = df.withColumn("year_diff", df["Year"] - lag(df["Year"]).over(window_part)) df = df.withColumn("group_id", sum(when(df["year_diff"] > 1, 1).otherwise(0)).over(window_part).fillna(0)) # 筛选每个分组的第一条记录 window_rn = Window.partitionBy("Org", "group_id").orderBy("Year") result_df = df.withColumn("rn", row_number().over(window_rn)) \ .filter(df["rn"] == 1) \ .drop("year_diff", "group_id", "rn") # 输出结果 result_df.orderBy("Org", "Year").show()
内容的提问来源于stack exchange,提问作者PS08
相关产品推荐
相关产品推荐

