You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python编写函数将年度人口数据插值为小时级时间序列

年度人口数据转小时级插值实现方案

现有代码核心问题

  • 初始化DataFrame时未指定列名,调用df_pop['name']等列属性会直接报错
  • 按区域名称循环时未筛选对应区域的年度数据,所有区域数据混用导致插值逻辑完全错误
  • scipy.interpolate.interp1d调用逻辑错误:该方法需先传入已知的x/y序列生成插值函数,再传入目标插值点计算结果,不可直接将目标点作为第三个参数传入
  • 插值的x轴维度不统一:已知点是年度整数,目标插值点是时间戳,需统一转换为年度浮点数值(如2015年6月对应2015.5)才能正确插值
  • 结果拼接逻辑错误,未将插值结果与时间序列、区域名称对应存储

修正后可运行代码

import pandas as pd
import random
from scipy.interpolate import interp1d

# 示例数据创建时指定列名
name = ['RI', 'NH', 'MA', 'RI', 'NH', 'MA','RI', 'NH', 'MA','RI', 'NH', 'MA']
year = [2015, 2015, 2015, 2016, 2016, 2016, 2017, 2017, 2017, 2018, 2018, 2018]
population = random.sample(range(10000, 300000), 12)
df_pop = pd.DataFrame(list(zip(name, year, population)), columns=['name', 'year', 'population'])

start_year = 2015 
end_year = 2018 

def pop_sum(df_pop, start_year, end_year):
    names = df_pop['name'].unique()
    res_list = []
    # 生成统一的小时级时间序列,pandas2.0+请将closed参数替换为inclusive='left'
    hour_series = pd.date_range(f'{start_year}-01-01', f'{end_year}-12-31', freq='1H', closed='left')
    # 转换为年度浮点值用于插值计算
    year_float = hour_series.year + (hour_series.dayofyear - 1)/365.25
    
    for name in names:
        # 筛选当前区域的年度数据
        sub_df = df_pop[df_pop['name'] == name].sort_values('year')
        t_known = sub_df['year'].values
        y_known = sub_df['population'].values
        # 生成插值函数,fill_value设置为外推防止边界点报错
        interp_func = interp1d(t_known, y_known, kind='linear', fill_value='extrapolate')
        # 计算小时级插值结果
        pop_interp = interp_func(year_float)
        # 拼接当前区域的结果
        tmp_df = pd.DataFrame({
            'hours': hour_series,
            'name': name,
            'population': pop_interp
        })
        res_list.append(tmp_df)
    # 合并所有区域的结果返回
    return pd.concat(res_list, ignore_index=True)

# 调用测试
hourly_pop = pop_sum(df_pop, start_year, end_year)
print(hourly_pop.head())

替代实现方案

如果不需要额外依赖scipy,也可以直接用pandas自带的重采样插值能力实现,逻辑更简洁:

def pop_sum_pandas(df_pop, start_year, end_year):
    df_list = []
    for name in df_pop['name'].unique():
        sub_df = df_pop[df_pop['name'] == name].copy()
        # 将年度数据关联到每年1月1日的时间点
        sub_df['dt'] = pd.to_datetime(sub_df['year'].astype(str) + '-01-01')
        sub_df = sub_df.set_index('dt')[['population']]
        # 重采样到小时级后线性插值
        hourly_sub = sub_df.resample('1H').interpolate(method='linear')
        # 筛选目标时间范围
        hourly_sub = hourly_sub.loc[f'{start_year}-01-01':f'{end_year}-12-31'].iloc[:-1]
        hourly_sub['name'] = name
        hourly_sub = hourly_sub.reset_index(names='hours')
        df_list.append(hourly_sub)
    return pd.concat(df_list, ignore_index=True)

内容的提问来源于stack exchange,提问作者KC Ray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 17:27:02