如何在Python中为数据集内指定日期的国家分配季节?
解决大型数据集按国家半球分配季节列的问题
核心思路
放弃iterrows/iteritems这类低效的行迭代方式,改用Pandas/Numpy矢量化操作处理——这是大数据集场景下的最优方案,既提升运行效率,又能避免迭代带来的索引错位、数据不更新等问题。整体步骤分为:
- 将日期列转为标准datetime格式,提取月份
- 标记每个国家所属的半球
- 根据半球规则批量映射季节
具体实现代码
1. 预处理:转换日期并提取月份
先确保日期列是Pandas可识别的datetime类型,再提取月份用于后续判断:
import pandas as pd import numpy as np # 假设数据集存储在df中,日期列名为'date',国家列名为'country' df['date'] = pd.to_datetime(df['date']) df['month'] = df['date'].dt.month
2. 标记国家所属半球
通过isin方法快速完成国家与半球的匹配:
# 替换为你实际的南北半球国家列表 north_hem_list = ["中国", "美国", "日本", ...] south_hem_list = ["澳大利亚", "巴西", "南非", ...] df['is_north'] = df['country'].isin(north_hem_list)
3. 矢量化映射季节(推荐方案,效率最高)
用np.where结合np.select实现批量判断,完全避免行迭代:
# 北半球季节规则 north_conditions = [ df['month'].between(3, 5), df['month'].between(6, 8), df['month'].between(9, 11), df['month'].isin([12, 1, 2]) ] north_seasons = ['Spring', 'Summer', 'Fall', 'Winter'] # 南半球季节规则 south_conditions = [ df['month'].between(9, 11), df['month'].isin([12, 1, 2]), df['month'].between(3, 5), df['month'].between(6, 8) ] south_seasons = ['Spring', 'Summer', 'Fall', 'Winter'] # 分配季节列,同时处理未匹配到半球的国家 df['season'] = np.where( df['is_north'], np.select(north_conditions, north_seasons, default='Unknown'), np.select(south_conditions, south_seasons, default='Unknown') )
备选方案:自定义函数+apply(适合逻辑复杂场景)
如果需要更灵活的分支逻辑,可使用apply,但效率略低于矢量化操作:
def get_season(row): month = row['month'] country = row['country'] if country in north_hem_list: if 3 <= month <= 5: return 'Spring' elif 6 <= month <= 8: return 'Summer' elif 9 <= month <= 11: return 'Fall' else: return 'Winter' elif country in south_hem_list: if 9 <= month <= 11: return 'Spring' elif month in [12, 1, 2]: return 'Summer' elif 3 <= month <= 5: return 'Fall' else: return 'Winter' else: return 'Unknown' df['season'] = df.apply(get_season, axis=1)
为什么iterrows/iteritems会失败?
这类行迭代方法有两个致命问题:
- 效率极差:大型数据集下,迭代每一行的时间成本是矢量化操作的数十倍甚至上百倍
- 易出错:迭代返回的是行的副本而非原数据,修改时容易出现索引错位、数据不更新的情况
内容的提问来源于stack exchange,提问作者Raul Martz
相关产品推荐
相关产品推荐

