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

Pandas跨时间戳多组行前向填充高效方案求助

高效实现Pandas跨时间戳多组行前向填充

需要实现的需求:将同一时间戳下的多个非NaN Name 作为一组,前向传播填充到后续所有时间戳行中,直到下一组非NaN Name 出现。现有循环实现处理10万行数据时效率低下,需高效解决方案。

输入数据

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'Timestamp': [
        pd.Timestamp('19/01/2022  10:00:00'),
        pd.Timestamp('19/01/2022  10:00:00'),
        pd.Timestamp('19/01/2022  15:00:00'),
        pd.Timestamp('19/01/2022  15:30:00'),
        pd.Timestamp('19/01/2022  16:00:00'),
        pd.Timestamp('19/01/2022  19:30:00'),
        pd.Timestamp('19/01/2022  20:00:00'),
        pd.Timestamp('19/01/2022  20:30:00'),
        pd.Timestamp('20/01/2022  13:00:00'),
        pd.Timestamp('20/01/2022  13:30:00'),
        pd.Timestamp('20/01/2022  14:00:00'),
        pd.Timestamp('20/01/2022  14:50:00'),
        pd.Timestamp('20/01/2022  15:00:00')],
    'Name': [
        'A', 'B', np.NaN, np.NaN, np.NaN,
        'C', np.NaN, np.NaN, np.NaN, np.NaN, np.NaN,
        'D', np.NaN]})

期望输出

desired_output = pd.DataFrame({
    'Timestamp': [
        pd.Timestamp('19/01/2022  10:00:00'),
        pd.Timestamp('19/01/2022  10:00:00'),
        pd.Timestamp('19/01/2022  15:00:00'),
        pd.Timestamp('19/01/2022  15:00:00'),
        pd.Timestamp('19/01/2022  15:30:00'),
        pd.Timestamp('19/01/2022  15:30:00'),
        pd.Timestamp('19/01/2022  16:00:00'),
        pd.Timestamp('19/01/2022  16:00:00'),
        pd.Timestamp('19/01/2022  19:30:00'),
        pd.Timestamp('19/01/2022  20:00:00'),
        pd.Timestamp('19/01/2022  20:30:00'),
        pd.Timestamp('20/01/2022  13:00:00'),
        pd.Timestamp('20/01/2022  13:30:00'),
        pd.Timestamp('20/01/2022  14:00:00'),
        pd.Timestamp('20/01/2022  14:50:00'),
        pd.Timestamp('20/01/2022  15:00:00')],
    'Name': [
        'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B',
        'C', 'C', 'C', 'C', 'C', 'C',
        'D', 'D']})

现有低效循环实现

import time

t0 = time.time()

unique_timestamps = df.Timestamp.unique()
new_entries = []
last_valid = None
for ut in unique_timestamps:
    val = df[df.Timestamp == ut]['Name'].values
    if isinstance(val[0], float) and np.isnan(val[0]) and last_valid is not None:
        new_entries.append(pd.DataFrame({'Timestamp': ut, 
                                         'Name': last_valid}))
    else:
        last_valid = df[df.Timestamp == ut]['Name']
output = pd.concat([df, pd.concat(new_entries)]).dropna().sort_values('Timestamp')

t1 = time.time()
print(f"耗时:{t1-t0}s")

高效矢量化解决方案

利用Pandas的分组、聚合和映射操作实现全矢量化处理,避免循环,大幅提升处理效率:

# 1. 按Timestamp分组,提取每个时间戳的非NaN Name列表
grouped = df.groupby('Timestamp')['Name'].agg(lambda x: x.dropna().tolist())

# 2. 创建填充组标识:遇到非空Name列表时生成新组,否则继承上一组的标识
group_key = (grouped.str.len() > 0).cumsum()

# 3. 提取每个组对应的Name列表,用组标识映射实现前向填充
name_mapping = grouped[grouped.str.len() > 0]
filled_names = group_key.map(name_mapping)

# 4. 将每个时间戳的Name列表展开为多行,得到最终结果
result = filled_names.explode().reset_index()

# 验证结果是否匹配期望输出(无输出则表示完全匹配)
print(pd.testing.assert_frame_equal(result, desired_output, check_dtype=False))

方案优势

  • 全程使用Pandas底层优化的矢量化操作,避免Python循环的性能开销
  • 处理10万行级数据时,效率比循环实现提升数倍甚至数十倍
  • 代码简洁逻辑清晰,易于维护和扩展

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:20:58