Как правильно отобразить дату века в Пандах? - PullRequest
11 голосов
/ 18 апреля 2019

У меня есть следующие данные в одном из моих столбцов:

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?

Ответы [ 5 ]

5 голосов
/ 18 апреля 2019

В этом конкретном случае я бы использовал это:

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

Обратите внимание, что это сломается, если у вас есть DOB после 1999 года!

Выход:

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]
4 голосов
/ 18 апреля 2019

Вы можете сначала преобразовать в дату и время, если годы выше или равны 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

Или вы можете добавить 19 или 20 к годам на Series.str.replace и установить значения на 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
1 голос
/ 18 апреля 2019

Другое решение состоит в том, чтобы рассматривать 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))
0 голосов
/ 18 апреля 2019

Вы можете использовать приведенный ниже код, если есть только 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]
0 голосов
/ 18 апреля 2019

В целом (в случае неопределенности) было бы лучше явно указать год:

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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...