【问题标题】:Converting pandas column to date, with many type of dates将 pandas 列转换为日期,具有多种日期
【发布时间】:2025-12-06 13:55:02
【问题描述】:

如何将下面的日期列转换为单个格式化的日期列?

df = pd.DataFrame(data={'datecol': ["-",
                                    "44198",
                                    "2021/01/01", 
                                    "14.04.20",
                                    "2021-13-03"]})

print(df.dropna()) 应该返回以下结果:

      datecol
0  2021-01-02
1  2021-01-01
2  2020-04-14
3  2021-03-13

谢谢!

【问题讨论】:

  • "44198" 在 Python 中不是可识别的日期格式。您大概是从 Excel 中获得的,其中数字代表 1899 年 12 月 31 日之后的天数
  • 我知道,我正在为更广泛的问题进行缩减。在最初的问题中,我尝试使用 (datetime.utcfromtimestamp(0) + timedelta(df[col].astype(int))).strftime("%Y-%m-%d") 之类的东西,但我无法解释任何可能的格式......

标签: python pandas datetime


【解决方案1】:
  1. 使用pd.to_datetime 转换所有有效的日期时间格式,为无法识别的格式指定格式
  2. 转换所有整数 (Excel) 日期。
  3. 将两者与fillna 结合使用
parsed = pd.to_datetime(df["datecol"], errors="coerce").fillna(pd.to_datetime(df["datecol"],format="%Y-%d-%m",errors="coerce"))
ordinal = pd.to_numeric(df["datecol"], errors="coerce").apply(lambda x: pd.Timestamp("1899-12-30")+pd.Timedelta(x, unit="D"))

df["datecol"] = parsed.fillna(ordinal)

>>> df
     datecol
0        NaT
1 2021-01-02
2 2021-01-01
3 2020-04-14
4 2021-03-13

【讨论】:

    【解决方案2】:

    如果一列包含多种格式,您将需要使用不同格式多次解析该列,并使用combine_first 组合生成的信息。因为我们指定了errors='coerce',所以日期格式应该只匹配一种格式。

    另一个小问题是,您的某些格式要求您只指定 format 参数,而其他格式则需要 originunit 参数。我们可以将kwargs 的字典传递给pd.to_datetime 函数来处理这个问题。

    请注意,任何数值都适用于originunit,因此如果您的日期列的值代表同一列中具有不同偏移量的不同单位,则不能使用此方法。在这种情况下,您需要提供其他逻辑来指示哪些单位和偏移量与哪些行相关。

    import pandas as pd
    from functools import reduce 
    
    kwl = [{'format': '%Y/%m/%d'},
           {'format': '%d.%m.%y'},
           {'format': '%Y-%d-%m'},
           {'format': '%Y/%m/%d'},
           {'unit': 'd', 'origin': '1899-12-30'}]]
    
    l = []
    for kwargs in kwl:
        if 'unit' in kwargs.keys():
            s = pd.to_numeric(df['datecol'], errors='coerce')
        else:
            s = df['datecol']
            
        l.append(pd.to_datetime(s, errors='coerce', **kwargs))
    
    result = reduce(lambda l,r: l.combine_first(r), l)
    

    print(result)
    #0          NaT
    #1   2021-01-02
    #2   2021-01-01
    #3   2020-04-14
    #4   2021-03-13
    Name: datecol, dtype: datetime64[ns]
    

    【讨论】:

      最近更新 更多