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

如何在Python DataFrame的时间段内生成插值数值?

问题

现有一组包含周期序列(周期0、1、2……)的DataFrame数据,需要在相邻周期之间生成新的数值行,计算逻辑为:取相邻周期的value差值,按设定的分段数量均分,生成对应time_order和value的记录。

示例数据如下:

import pandas as pd

data = [{'metric': '3f00d0b5', 'time':52.66, 'time_order': 0, 'variable': 'var1', 'value': 0.035},
        {'metric': '3f00d0b5', 'time':422.4, 'time_order': 1, 'variable': 'var1', 'value': 0.512},
        {'metric': '3f00d0b5', 'time':620.1, 'time_order': 2, 'variable': 'var1', 'value': 0.0},
        
        {'metric': '3f00d0b5', 'time':52.66, 'time_order': 0, 'variable': 'var2', 'value': 0.007},
        {'metric': '3f00d0b5', 'time':422.4, 'time_order': 1, 'variable': 'var2', 'value': 0.012},
        {'metric': '3f00d0b5', 'time':620.1, 'time_order': 2, 'variable': 'var2', 'value': 0.214},
            
        {'metric': '83e7fdd1', 'time':25.42, 'time_order': 0, 'variable': 'var1', 'value': 0.0},
        {'metric': '83e7fdd1', 'time':322.45, 'time_order': 1, 'variable': 'var1', 'value': 0.241},
        {'metric': '83e7fdd1', 'time':678.12, 'time_order': 2, 'variable': 'var1', 'value': 0.005},
        
        {'metric': '83e7fdd1', 'time':25.42, 'time_order': 0, 'variable': 'var2', 'value': 0.02},
        {'metric': '83e7fdd1', 'time':322.45, 'time_order': 1, 'variable': 'var2', 'value': 0.007},
        {'metric': '83e7fdd1', 'time':678.12, 'time_order': 2, 'variable': 'var2', 'value': 0.0}
]
    
df = pd.DataFrame.from_dict(data)

期望结果示例(以metric=3f00d0b5, variable=var1的相邻周期0和1为例):

{'metric': '3f00d0b5',  'time':52.66, 'time_order': 0, 'variable': 'var1', 'value': 0.035},
{'metric': '3f00d0b5',  'time':52.66, 'time_order': 0.1, 'variable': 'var1', 'value': 0.083},
...
{'metric': '3f00d0b5',  'time':52.66, 'time_order': 0.9, 'variable': 'var1', 'value': 0.4643},
{'metric': '3f00d0b5',  'time':422.4, 'time_order': 1, 'variable': 'var1', 'value': 0.512},

需要简洁的Pythonic实现方式。


简洁实现方案

可以利用Pandas的分组、线性插值功能实现,核心思路是按metric和variable分组,对每组内的相邻周期数据生成均分的中间值,以下两种方式都能满足需求:

方式一:直观分段生成

适合需要自定义插值逻辑的场景,代码清晰易懂:

n = 10  # 相邻周期间分成10份,生成9个中间行

# 按维度分组并确保每组内按周期排序
groups = df.sort_values(['metric', 'variable', 'time_order']).groupby(['metric', 'variable'])

def interpolate_group(group):
    expanded = []
    orders = group['time_order'].values
    values = group['value'].values
    times = group['time'].values
    metric = group['metric'].iloc[0]
    var = group['variable'].iloc[0]
    
    for i in range(len(orders)-1):
        # 生成当前周期到下一个周期的均分序列(不含终点,避免重复)
        order_steps = pd.linspace(orders[i], orders[i+1], num=n, endpoint=False)
        val_steps = pd.linspace(values[i], values[i+1], num=n, endpoint=False)
        
        # 构造当前段的行数据
        segment = pd.DataFrame({
            'metric': metric,
            'time': times[i],
            'time_order': order_steps,
            'variable': var,
            'value': val_steps
        })
        expanded.append(segment)
    
    # 添加分组的最后一行原始数据
    expanded.append(group.iloc[[-1]])
    return pd.concat(expanded, ignore_index=True)

# 应用分组逻辑并合并结果
result_df = groups.apply(interpolate_group).reset_index(drop=True)

方式二:利用Pandas内置插值

仅需线性插值时,代码更紧凑:

n = 10

groups = df.sort_values(['metric', 'variable', 'time_order']).groupby(['metric', 'variable'])

def interpolate_group_compact(group):
    # 生成所有需要的time_order序列
    original_orders = group['time_order'].values
    new_orders = []
    for i in range(len(original_orders)-1):
        new_orders.extend(pd.linspace(original_orders[i], original_orders[i+1], num=n, endpoint=False))
    new_orders.append(original_orders[-1])
    
    # 重新索引并插值
    new_group = group.set_index('time_order').reindex(new_orders)
    new_group['value'] = new_group['value'].interpolate(method='linear')
    # 其他非数值字段用前向填充补全
    new_group[['metric', 'variable', 'time']] = new_group[['metric', 'variable', 'time']].ffill()
    
    return new_group.reset_index()

result_df_compact = groups.apply(interpolate_group_compact).reset_index(drop=True)

验证结果

执行以下代码查看指定维度的结果:

print(result_df[(result_df['metric'] == '3f00d0b5') & (result_df['variable'] == 'var1')].head(11))

输出会包含周期0的起始行、9个中间行和周期1的起始行,与预期一致。


内容的提问来源于stack exchange,提问作者Leonardo Ferreira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:00:59