Преобразование столбца «день» в дату и время со спецификацией года

#python #pandas #dataframe #datetime

#python #pandas #фрейм данных #дата и время

Вопрос:

У меня есть фрейм данных, который включает столбец с номерами дней, для которых известен год:

 print (df)
        year  day  time  
0       2012  227   800
15      2012  227   815
30      2012  227   830
...     ...   ...   ...
194250  2013  226  1645
194265  2013  226  1700
 

Я попытался преобразовать числа дней в дату %m-%d и время, используя:

 import pandas as pd    
df['day'] = pd.to_datetime(df['day'], format='%j').dt.strftime('%m-%d')
 

что дает:

         year    day  time
0       2012  08-15   800
15      2012  08-15   815
30      2012  08-15   830
...     ...   ...     ...
194250  2013  08-14  1645
194265  2013  08-14  1700
 

но это преобразование неверно, потому что 227-й день 2012 года приходится на 14 августа (08-14). Я считаю, что эта ошибка связана с отсутствием спецификации года в преобразовании.

Как я могу указать год в преобразовании, чтобы получить a) %Y-%m-%d ; b) %m-%d ; c) %Y-%m-%dT%H:%M из имеющегося у меня фрейма данных?

Спасибо

Ответ №1:

вы можете преобразовать в строку и передать в pd.to_datetime нее, которую вы предоставляете с правильной директивой синтаксического анализа:

 import pandas as pd

df = pd.DataFrame({'year': [2012, 2012], 'day' : [227, 228], 'time': [800, 0]})

df['datetime'] = pd.to_datetime(df.year.astype(str)   ' '  
                                df.day.astype(str)   ' '  
                                df.time.astype(str).str.zfill(4), 
                                format='%Y %j %H%M')

df['datetime']

0   2012-08-14 08:00:00
1   2012-08-15 00:00:00
Name: datetime, dtype: datetime64[ns]
 

Форматирование в строку — это просто вызов strftime dt средства доступа via, например

 df['datetime'].dt.strftime('%Y-%m-%dT%H:%M')

0    2012-08-14T08:00
1    2012-08-15T00:00
Name: datetime, dtype: object
 

Комментарии:

1. является ли целью zfill (4) превращать времена без начального нуля во времена с четырьмя цифрами (т.Е. Включая начальный ноль)? В сочетании с кодом QH ваш код правильно указывал все времена даже без zfill. Спасибо!

2. @R_Dax точно 🙂 Это не сработало, когда я тестировал, например 0 , для 00:00 часов (т. Е. Что-то меньшее, чем 3 цифры), поэтому я добавил zfill.

3. Хорошо, я понимаю. Возможно, это было хорошо для меня в данном конкретном случае, поскольку все мои времена имеют не менее 3 цифр (то есть (0) от 800 до 1700), но это поможет в будущих случаях с временными форматами менее 3 цифр. Спасибо! 🙂

Ответ №2:

Вы можете попробовать преобразовать year в тип datetime и day в тип timedelta, не забудьте сместить дату:

 dates = pd.to_datetime(df['year'], format='%Y')   
        pd.to_timedelta(df['day'] -1, unit='D')  
 

Вывод:

 0        2012-08-14
15       2012-08-14
30       2012-08-14
194250   2013-08-14
194265   2013-08-14
dtype: datetime64[ns]
 

Затем извлеките дату-месяц с помощью strftime :

 df['day'] = dates.dt.strftime('%M-%D')
 

Комментарии:

1. Quang Hoang ваше решение работает для решения проблемы даты и времени для всего df, но не добавляет информацию о времени. Решение MrFuppes добавляет информацию о времени, но я смог заставить ее работать только для одной строки, а не для всего df. Я объединил оба решения: QH для преобразования day-> date, затем MF для добавления информации о времени. Большое вам обоим спасибо. Извините, я не могу показаться @ anyone в комментарии.