Python计算含缺失值的时间序列首尾有效数据百分比变化
完全可以自动化实现,iterrows 方法也能满足需求,下面给出具体实现方案,同时也提供更高效的pandas向量化写法供你选择:
前提是你已经把数据读入pandas DataFrame,命名为df。
第一步:预处理年份列
import pandas as pd import numpy as np # 提取所有年份列,按年份从小到大排序,保证时间顺序正确 year_cols = [col for col in df.columns if col.startswith('YR')] year_cols_sorted = sorted(year_cols, key=lambda x: int(x.replace('YR', '')))
方案1:用iterrows实现
result_list = [] for _, row in df.iterrows(): current_iso = row['iso'] # 过滤当前行的非空有效值 valid_data = row[year_cols_sorted].dropna() # 边界判断:有效数据不足2个无法计算变化率 if len(valid_data) < 2: res = { 'iso': current_iso, 'earliest_year': None, 'earliest_value': None, 'latest_year': None, 'latest_value': None, 'pct_change': None } else: earliest_val = valid_data.iloc[0] earliest_year = valid_data.index[0].replace('YR', '') latest_val = valid_data.iloc[-1] latest_year = valid_data.index[-1].replace('YR', '') # 避免除0报错 if earliest_val == 0: pct = None else: pct = round((latest_val - earliest_val) / earliest_val * 100, 2) res = { 'iso': current_iso, 'earliest_year': earliest_year, 'earliest_value': earliest_val, 'latest_year': latest_year, 'latest_value': latest_val, 'pct_change': pct } result_list.append(res) # 结果转DataFrame result_df = pd.DataFrame(result_list)
方案2:用apply实现(更适合大数据量场景,代码更简洁)
def calc_change(row): valid_data = row[year_cols_sorted].dropna() if len(valid_data) < 2 or valid_data.iloc[0] == 0: return pd.Series([None, None, None, None, None]) earliest_val = valid_data.iloc[0] earliest_year = valid_data.index[0].replace('YR', '') latest_val = valid_data.iloc[-1] latest_year = valid_data.index[-1].replace('YR', '') pct = round((latest_val - earliest_val) / earliest_val * 100, 2) return pd.Series([earliest_year, earliest_val, latest_year, latest_val, pct]) # 直接把计算结果追加到原表 df[['earliest_year', 'earliest_value', 'latest_year', 'latest_value', 'pct_change']] = df.apply(calc_change, axis=1)
结果验证
拿你给出的样例数据测试,输出结果和需求完全匹配:
- ZWE:最早年份2011数值22.5,最晚年份2019数值38.3,百分比变化约70.22%
- ZMB:最早年份2010数值54.7,最晚年份2015数值54.4,百分比变化约-0.55%
注意事项
- 代码已经加了边界处理逻辑,你可以根据自己的业务需求调整空值、除0场景的返回规则
- 如果数据量小于1万行,两种方案差异不大;如果数据量很大,优先选
apply方案,运行效率远高于iterrows
内容的提问来源于stack exchange,提问作者sophie395
相关产品推荐
相关产品推荐

