【问题标题】:How to display the correct date century in Pandas?如何在 Pandas 中显示正确的日期世纪?
【发布时间】:2019-09-08 10:08:01
【问题描述】:

我的某一列中有以下数据:

df['DOB']

0    01-01-84
1    31-07-85
2    24-08-85
3    30-12-93
4    09-12-77
5    08-09-90
6    01-06-88
7    04-10-89
8    15-11-91
9    01-06-68
Name: DOB, dtype: object

我想将其转换为数据类型列。 我尝试了以下操作:

print(pd.to_datetime(df1['Date.of.Birth']))
0   1984-01-01
1   1985-07-31
2   1985-08-24
3   1993-12-30
4   1977-09-12
5   1990-08-09
6   1988-01-06
7   1989-04-10
8   1991-11-15
9   2068-01-06
Name: DOB, dtype: datetime64[ns]

我怎样才能得到日期为 1968-01-06 而不是 2068-01-06?

【问题讨论】:

    标签: python pandas date


    【解决方案1】:

    在这种特定的情况下,我会使用这个:

    pd.to_datetime(df['DOB'].str[:-2] + '19' + df['DOB'].str[-2:])
    

    请注意,如果您在 1999 年之后有 DOB,这将中断!

    输出:

    0   1984-01-01
    1   1985-07-31
    2   1985-08-24
    3   1993-12-30
    4   1977-09-12
    5   1990-08-09
    6   1988-01-06
    7   1989-04-10
    8   1991-11-15
    9   1968-01-06
    dtype: datetime64[ns]
    

    【讨论】:

    • 获取未定义的错误系列。希望这是一个错字,必须使用列名。
    • @Madan 是的,我想更改答案以适应问题,但忘记修改第二个参考。固定。
    • @jezrael 是的,将编辑问题以明确说明
    • 谢谢@jezrael。我不会在我的文件中获得年份 > 1999 的日期。
    【解决方案2】:

    您可以先转换为日期时间,如果年份大于或等于 2020,则减去 100DateOffset 创建的年份:

    df['DOB'] = pd.to_datetime(df['DOB'], format='%d-%m-%y')
    df.loc[df['DOB'].dt.year >= 2020, 'DOB'] -= pd.DateOffset(years=100)
    #same like
    #mask = df['DOB'].dt.year >= 2020
    #df.loc[mask, 'DOB'] = df.loc[mask, 'DOB'] - pd.DateOffset(years=100)
    print (df)
             DOB
    0 1984-01-01
    1 1985-07-31
    2 1985-08-24
    3 1993-12-30
    4 1977-12-09
    5 1990-09-08
    6 1988-06-01
    7 1989-10-04
    8 1991-11-15
    9 1968-06-01
    

    或者您可以通过Series.str.replace1920 添加到年份,并通过numpy.where 设置值。

    注意:解决方案也适用于 00 多年 2000,直至 2020

    s1 = df['DOB'].str.replace(r'-(\d+)$', r'-19\1')
    s2 = df['DOB'].str.replace(r'-(\d+)$', r'-20\1')
    mask = df['DOB'].str[-2:].astype(int) <= 20
    df['DOB'] = pd.to_datetime(np.where(mask, s2, s1))
    
    print (df)
             DOB
    0 1984-01-01
    1 1985-07-31
    2 1985-08-24
    3 1993-12-30
    4 1977-09-12
    5 1990-08-09
    6 1988-01-06
    7 1989-04-10
    8 1991-11-15
    9 1968-01-06
    

    如果所有年份都低于2000

    s1 = df['DOB'].str.replace(r'-(\d+)$', r'-19\1')
    df['DOB'] = pd.to_datetime(s1, format='%d-%m-%Y')
    print (df)
             DOB
    0 1984-01-01
    1 1985-07-31
    2 1985-08-24
    3 1993-12-30
    4 1977-12-09
    5 1990-09-08
    6 1988-06-01
    7 1989-10-04
    8 1991-11-15
    9 1968-06-01
    

    【讨论】:

    • 能否解释一下这一行:df.loc[df['DOB'].dt.year >= 2020, 'DOB'] -= pd.DateOffset(years=100)
    • @Madan - 首先将值转换为日期时间,然后如果某些年份高于 2020,则使用 dateoffset 减去 100 年
    【解决方案3】:

    另一种解决方案是将 DOB 视为一个日期,仅当它在未来(即“现在”之后)时才将其返回到上一个世纪。示例:

    from datetime import datetime, date
    
    df=pd.DataFrame.from_dict({'DOB':['01-06-68','01-06-08']})
    df['DOB'] = df['DOB'].apply(lambda x: datetime.strptime(x,'%d-%m-%y'))
    df['DOB'] = df['DOB'].apply(lambda x: x if x<datetime.now() else date(x.year-100,x.month,x.day))
    

    【讨论】:

      【解决方案4】:

      一般情况下(在不确定的情况下),最好明确指定年份:

      pd.to_datetime(data['Date.of.Birth'].apply(lambda x: '-'.join(x.split('-')[:-1] + ['19' + x.split('-')[2]])))
      

      我使用以下数据框运行它:

          0   1
      0   0   01-01-84
      1   1   31-07-85
      2   2   24-08-85
      3   3   30-12-93
      4   4   09-12-77
      5   5   08-09-90
      6   6   01-06-88
      7   7   04-10-89
      8   8   15-11-91
      9   9   01-06-68
      
      
      pd.to_datetime(data[1].apply(lambda x: '-'.join(x.split('-')[:-1] + ['19' + x.split('-')[2]])))
      
      
      0   1984-01-01
      1   1985-07-31
      2   1985-08-24
      3   1993-12-30
      4   1977-09-12
      5   1990-08-09
      6   1988-01-06
      7   1989-04-10
      8   1991-11-15
      9   1968-01-06
      Name: 1, dtype: datetime64[ns]
      

      【讨论】:

        【解决方案5】:

        如果只有1920作为开头,你可以使用下面的代码,比如:

        df['DOB'] = pd.to_datetime(df['DOB'].str.replace('20([^20]*)$', '19'))
        

        如果其他地方没有20s:

        df['DOB'] = pd.to_datetime(df['DOB'].str.replace('20', '19'))
        

        现在:

        print(df['DOB'])
        

        是:

        0   1984-01-01
        1   1985-07-31
        2   1985-08-24
        3   1993-12-30
        4   1977-09-12
        5   1990-08-09
        6   1988-01-06
        7   1989-04-10
        8   1991-11-15
        9   1968-01-06
        dtype: datetime64[ns]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-08-11
          • 1970-01-01
          • 1970-01-01
          • 2013-11-24
          • 2017-11-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多