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

使用np.where()创建DataFrame新列时遇格式错误的解决咨询

解决DataFrame基于条件创建新列时的np.where筛选失效问题

需求说明

要在DataFrame中生成名为New的新列,规则如下:

  • 当MinDate列值为空时,直接取Start_Date列的数据
  • 当MinDate列值不为空时,将该列日期转为字符串后与Time列的时间字符串拼接,再转回datetime格式

原代码及错误信息

原实现代码:

import pandas as pd
import numpy as np
from datetime import date, datetime

fffg = pd.DataFrame({'N': [1, 2, 3], 'MinDate': [date(2023,1,2), None, date(2022,1,7)], 
              'Time': [datetime.time(8, 48, 0), datetime.time(8, 48, 0), datetime.time(8, 48, 0)], 
              'Start_Date': [datetime(2022,4,1,15,10), datetime(2023,4,1,15,10), datetime(2022,5,1,15,10)]})
fffg['MinDate'] = pd.to_datetime(fffg['MinDate'])
fffg['New'] = np.where(pd.notnull(fffg['MinDate']),  
                       pd.to_datetime(fffg['MinDate'].astype(str)+' '+fffg['Time'].astype(str)),
                       fffg['Start_Date']
                       )                       
fffg

运行后报错:

ValueError: time data "NaT 08:48:00" doesn't match format "%Y-%m-%d %H:%M:%S", at position 1. You might want to try:
    - passing `format` if your strings have a consistent format;
    - passing `format='ISO8601'` if your strings are all ISO8601 but not necessarily in exactly the same format;
    - passing `format='mixed'`, and the format will be inferred for each element individually. You might want to use `dayfirst` alongside this.

问题原因

np.where的执行逻辑是先完整计算两个分支的所有元素,再根据条件选择对应结果。即使MinDate为NaT(空值),对应的行仍会执行字符串拼接操作,生成"NaT 08:48:00"这种无法被pd.to_datetime解析的无效时间字符串,最终触发报错。

解决方案

方案1:使用apply逐行处理

逐行判断条件,仅对符合要求的行执行拼接转换,避免无效计算:

import pandas as pd
from datetime import date, datetime

fffg = pd.DataFrame({'N': [1, 2, 3], 'MinDate': [date(2023,1,2), None, date(2022,1,7)], 
              'Time': [datetime.time(8, 48, 0), datetime.time(8, 48, 0), datetime.time(8, 48, 0)], 
              'Start_Date': [datetime(2022,4,1,15,10), datetime(2023,4,1,15,10), datetime(2022,5,1,15,10)]})
fffg['MinDate'] = pd.to_datetime(fffg['MinDate'])

def create_new_col(row):
    if pd.notnull(row['MinDate']):
        return pd.to_datetime(f"{row['MinDate'].date()} {row['Time']}")
    return row['Start_Date']

fffg['New'] = fffg.apply(create_new_col, axis=1)
print(fffg)

方案2:分步处理(适合大数据集,性能更优)

先初始化新列为Start_Date,再筛选出MinDate非空的行执行拼接转换,利用pandas向量化操作提升性能:

import pandas as pd
from datetime import date, datetime

fffg = pd.DataFrame({'N': [1, 2, 3], 'MinDate': [date(2023,1,2), None, date(2022,1,7)], 
              'Time': [datetime.time(8, 48, 0), datetime.time(8, 48, 0), datetime.time(8, 48, 0)], 
              'Start_Date': [datetime(2022,4,1,15,10), datetime(2023,4,1,15,10), datetime(2022,5,1,15,10)]})
fffg['MinDate'] = pd.to_datetime(fffg['MinDate'])

# 初始化New列为Start_Date
fffg['New'] = fffg['Start_Date']
# 筛选MinDate非空的行,执行拼接转换
valid_mask = pd.notnull(fffg['MinDate'])
fffg.loc[valid_mask, 'New'] = pd.to_datetime(
    fffg.loc[valid_mask, 'MinDate'].astype(str) + ' ' + fffg.loc[valid_mask, 'Time'].astype(str)
)
print(fffg)

补充说明

方案2通过掩码筛选只处理需要转换的行,避免了对全列执行无效操作,在处理大型数据集时性能远优于逐行循环的apply方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:30:15