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

Pandas按name_id补全缺失时间行并去重问题求助

解决Pandas分组补全小时时间序列并保留name_id的问题

嘿,作为Pandas新手碰到这种时间序列补全的问题确实容易卡壳,我来帮你一步步搞定这个需求!咱们既要补全每个name_id下当日00:00-23:00的缺失小时行,还要去重(包括夏令时导致的重复时间),最后还得保留name_id列不丢失,安排!

整体思路拆解

  1. 先把时间列解析正确:尤其是你的输入是dd/mm/yyyy格式,得指定解析规则,还要考虑时区(应对夏令时的时间变化)。
  2. 彻底移除重复行:不管是普通重复还是夏令时导致的同一小时重复,都通过name_id+datetime的组合去重。
  3. 分组补全小时序列:按name_id+日期分组,给每个组生成当日完整的24小时序列,再和原数据合并补NaN。
  4. 整理成你要的输出格式:把每个name_id对应日期的value列表整理好,同时保留name_id。

完整代码实现

import pandas as pd
import numpy as np

# 先把你的示例输入转成DataFrame
data = {
    'name_id': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'],
    'datetime': ['23/01/2020 0:00:00', '23/01/2020 1:00:00', '23/01/2020 2:00:00',
                 '23/01/2020 3:00:00', '23/01/2020 3:00:00', '23/01/2020 4:00:00',
                 '23/01/2020 5:00:00', '23/01/2020 0:00:00', '23/01/2020 1:00:00',
                 '23/01/2020 2:00:00', '23/01/2020 3:00:00', '23/01/2020 6:00:00'],
    'value': [100, 98, 96, 99, 99, 98, 99, 144, 324, 367, 368, 364]
}

df = pd.DataFrame(data)

# 1. 解析时间列:指定格式为dd/mm/yyyy HH:MM:SS,添加时区(这里用欧洲伦敦时区,可根据你的数据调整)
# 加时区是为了正确识别夏令时的时间变化,避免处理重复行出错
df['datetime'] = pd.to_datetime(df['datetime'], format='%d/%m/%Y %H:%M:%S', tz='Europe/London')

# 2. 移除重复行:按name_id和datetime组合去重,保留第一行
df = df.drop_duplicates(subset=['name_id', 'datetime'], keep='first')

# 3. 定义补全小时序列的函数
def fill_hourly_group(group):
    # 获取当前组的日期(同一组的日期都是相同的)
    current_date = group['datetime'].dt.date.iloc[0]
    # 生成当日00:00到23:00的完整小时序列
    full_hour_range = pd.date_range(
        start=f"{current_date} 00:00:00",
        end=f"{current_date} 23:00:00",
        freq='H',
        tz='Europe/London'
    )
    # 转成DataFrame用于合并
    full_hour_df = pd.DataFrame({'datetime': full_hour_range})
    # 和原组数据合并,缺失的value自动设为NaN
    merged_df = pd.merge(full_hour_df, group, on='datetime', how='left')
    # 给合并后的df填充name_id(同一组的name_id相同)
    merged_df['name_id'] = group['name_id'].iloc[0]
    return merged_df

# 按name_id和日期分组,应用补全函数
df['date'] = df['datetime'].dt.date
filled_result = df.groupby(['name_id', 'date']).apply(fill_hourly_group).reset_index(drop=True)

# 删掉临时的date列
filled_result = filled_result.drop('date', axis=1)

# 4. 整理成每个name_id对应日期的value列表(按需选择)
final_output = filled_result.groupby(
    ['name_id', filled_result['datetime'].dt.date]
)['value'].apply(list).reset_index()
final_output.columns = ['name_id', 'date', 'value_list']

# 打印看看结果
print(final_output)

关键说明

  • 之前的参考代码丢失name_id,是因为分组后只对value列应用函数,没有保留组内的name_id信息。咱们的函数里通过group['name_id'].iloc[0]给补全后的行填充了对应的name_id,就不会丢失啦。
  • 时区的设置很重要:如果你的数据涉及夏令时(比如时钟回拨导致同一小时出现两次),带时区的datetime能帮你正确识别这些重复时间,去重更准确。如果你的数据没有时区,可以去掉tz参数,但要注意夏令时场景的处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:09:11