如何在 Pandas 中显示正确的日期世纪?
Posted
技术标签:
【中文标题】如何在 Pandas 中显示正确的日期世纪?【英文标题】:How to display the correct date century in 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?
【问题讨论】:
【参考方案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
,则减去 100
由 DateOffset
创建的年份:
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.replace
将19
或20
添加到年份,并通过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】:如果只有19
和20
作为开头,你可以使用下面的代码,比如:
df['DOB'] = pd.to_datetime(df['DOB'].str.replace('20([^20]*)$', '19'))
如果其他地方没有20
s:
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]
【讨论】:
以上是关于如何在 Pandas 中显示正确的日期世纪?的主要内容,如果未能解决你的问题,请参考以下文章
如何在数据框中为 Pandas 日期时间对象正确设置 Datetimeindex?