如何用Pandas DataFrame.groupby()对气象数据按连续季节集群分组?
这个问题我之前也碰到过!普通的groupby('season')确实会把所有相同季节的数据捏到一起,不管它们是不是连续的时间段。要实现按连续的季节集群分组,核心是给每一段连续的相同季节分配一个唯一的标识,然后用这个标识来分组。
第一步:确保数据按时间排序
这是前提!如果你的数据不是按时间顺序排列的,连续季节的判断就会完全出错。假设你的DataFrame有一个日期列(比如date),先排序:
df = df.sort_values('date').reset_index(drop=True)
第二步:创建连续季节集群的标识列
我们可以通过比较当前行和上一行的season值,标记季节变化的位置,然后对这些变化点累加,得到每个连续集群的唯一ID:
# 标记当前行与上一行季节不同的位置 df['season_changed'] = df['season'] != df['season'].shift() # 累加变化点,生成唯一的集群ID df['season_cluster'] = df['season_changed'].cumsum()
简单解释下:shift()会把上一行的season值移到当前行,和当前行比较——不同就返回True(等价于1),相同返回False(等价于0)。cumsum()会把这些1累加,每次遇到季节变化时,集群ID就加1,这样同一段连续的季节会共享同一个ID。
第三步:按集群ID分组
现在用season_cluster来分组,就能得到每一段连续的季节数据了:
# 按集群分组,计算每个连续季节的降雨量统计,比如求和/均值 grouped_rainfall = df.groupby('season_cluster')['rainfall'].agg(['sum', 'mean'])
如果想同时保留季节信息,可以把season和season_cluster一起作为分组键:
grouped_with_season = df.groupby(['season', 'season_cluster'])['rainfall'].agg(['sum', 'mean'])
举个实际例子
假设你的原始数据是这样的:
| date | season | rainfall |
|---|---|---|
| 2020-12-01 | winter | 5 |
| 2021-01-01 | winter | 3 |
| 2021-03-01 | spring | 10 |
| 2021-12-01 | winter | 7 |
| 2022-01-01 | winter | 2 |
处理后season_cluster列会变成:
| date | season | rainfall | season_changed | season_cluster |
|---|---|---|---|---|
| 2020-12-01 | winter | 5 | True | 1 |
| 2021-01-01 | winter | 3 | False | 1 |
| 2021-03-01 | spring | 10 | True | 2 |
| 2021-12-01 | winter | 7 | True | 3 |
| 2022-01-01 | winter | 2 | False | 3 |
这样分组后,两个winter段就会被分成独立的组(cluster 1和cluster 3),完美解决你的需求!
注意事项
- 如果你的
season列有缺失值,建议先处理(比如用df.dropna(subset=['season'])删除,或者填充合理值),不然shift()后的比较会出现NaN,导致集群ID生成错误。 - 如果你的数据已经是按时间排序的,那第一步的排序可以省略,但最好还是加上,避免意外情况。
内容的提问来源于stack exchange,提问作者mcmahonS9
相关产品推荐
相关产品推荐

