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

如何用DataFrame的Hour列修改Datetime小时并处理异常值?

问题解决:处理DataFrame中带异常值的日期列转换及通用编辑方法

我有如下结构的DataFrame,Day列大部分是d-m-y格式的日期,但存在异常值(比如示例中的"7"):

import pandas as pd

AL = [
    ['1','10-12-2022','2022-12-17 00:00:00'],
    ['1','10-12-2022','2022-12-17 00:00:00'],
    ['1','7','2022-12-17 00:00:00']
]
    
df_long = pd.DataFrame(AL, columns=['Hour','Day','Day2'])

各列数据类型均为object:

Day               object
Day2              object
Hour              object
dtype: object 

需求是将Day列的正常日期条目替换小时为Hour列的数值,生成格式为dd-mm-yyyy HH:MM:SS的新列,但直接用pd.to_datetime转换会因异常值报错:

df_long['Day3']= pd.to_datetime(df_long['Day']) + pd.to_timedelta(df_long['Hour'])

报错信息:

error: time data "7" doesn't match format "%d-%m-%Y", at position 6. You might want to try:
    - passing `format` if your strings have a consistent format;

分步解决异常值问题并生成目标列

  1. 筛选有效日期行:用正则表达式匹配d-m-y格式的日期,生成布尔索引定位正常条目
  2. 转换并调整时间:对有效日期转换为datetime类型,加上Hour列对应的小时数
  3. 格式化输出:将调整后的datetime格式化为目标字符串格式,异常值可设为NaN或保留原内容

代码实现:

# 1. 匹配d-m-y格式的日期,生成布尔索引
valid_dates = df_long['Day'].str.match(r'^\d{1,2}-\d{1,2}-\d{4}$')

# 2. 初始化Day3列为空值(若要保留异常值原内容,改为df_long['Day3'] = df_long['Day'])
df_long['Day3'] = pd.NA

# 3. 处理有效日期行:转换日期+添加小时+格式化
df_long.loc[valid_dates, 'Day3'] = (
    pd.to_datetime(df_long.loc[valid_dates, 'Day'], format='%d-%m-%Y') 
    + pd.to_timedelta(df_long.loc[valid_dates, 'Hour'].astype(int), unit='h')
).dt.strftime('%d-%m-%Y %H:%M:%S')

输出结果:

HourDayDay2Day3
110-12-20222022-12-17 00:00:0010-12-2022 01:00:00
110-12-20222022-12-17 00:00:0010-12-2022 01:00:00
172022-12-17 00:00:00

DataFrame中选择并编辑特定条目的通用方法

1. 布尔索引筛选(最常用)

用df.loc[布尔条件, 目标列]定位符合要求的行,直接赋值修改:

# 示例:筛选Day列长度大于5的行,修改Day3
df_long.loc[df_long['Day'].str.len() > 5, 'Day3'] = '处理后的值'

2. 正则匹配筛选

针对字符串列,用str.match/str.contains精准匹配格式或内容:

# 匹配包含数字和连字符的日期格式行
target_rows = df_long['Day'].str.contains(r'\d+-\d+-\d+')
df_long.loc[target_rows, 'Day3'] = '匹配到的内容'

3. where/mask 方法

  • where:满足条件保留原值,不满足则替换为指定值
  • mask:与where相反,不满足条件保留原值,满足则替换
# 示例:有效日期保留处理后的值,否则设为NaN
df_long['Day3'] = (pd.to_datetime(df_long['Day'], format='%d-%m-%Y', errors='coerce') 
                   + pd.to_timedelta(df_long['Hour'].astype(int), unit='h')
                  ).dt.strftime('%d-%m-%Y %H:%M:%S').where(valid_dates, pd.NA)

4. apply结合自定义函数

对每行应用自定义逻辑,灵活处理复杂判断:

def process_row(row):
    # 判断Day是否为有效日期
    if pd.Series(row['Day']).str.match(r'^\d{1,2}-\d{1,2}-\d{4}$').iloc[0]:
        return (pd.to_datetime(row['Day'], format='%d-%m-%Y') + pd.to_timedelta(int(row['Hour']), unit='h')).strftime('%d-%m-%Y %H:%M:%S')
    else:
        return pd.NA

df_long['Day3'] = df_long.apply(process_row, axis=1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 07:32:12