Почему Python-панды назначают произвольную информацию о времени объекту datetime? - PullRequest
1 голос
/ 23 октября 2019

Python pandas (0.24.1) добавляет, казалось бы, произвольное количество часов, минут и секунд к моим объектам datetime. Это кажется неожиданным как поведение по умолчанию;Я ожидаю, что компонент времени по умолчанию установлен на полночь (00:00:00). Это ошибка?

import pandas as pd

df = pd.DataFrame( {'yr': [2019, 2019],
                    'mo': [9, 9],
                    'dy': [25, 26]}     )

df['dtime'] = ( pd.to_datetime(df['yr'],format='%Y')
               +pd.to_timedelta(df['mo']-1,unit='M')
               +pd.to_timedelta(df['dy']-1,unit='d') )


print('pandas version == '+pd.__version__)
df

################################################
OUTPUT:
################################################

pandas version == 0.24.1
yr  mo  dy  dtime
0   2019    9   25  2019-09-25 11:52:48
1   2019    9   26  2019-09-26 11:52:48

Ответы [ 2 ]

2 голосов
/ 23 октября 2019

Чтобы добавить подробности в отношении проблемы с timedelta, о которой говорил Джезраэль, проблема с преобразованием месяца выглядит следующим образом: Pandas timedelta определяет месяц как 1/12 года, что составляет 365,2425 дня на основе логики високосного года. ,

243 дня, 11:52:48 - 21037968 секунд.

>>> 243*60*60*24+11*60*60+52*60+48
21037968

Некоторые анализы подтверждают, что это 8/12 года, который длится 365,2425 дня.

>>> 21037968/((8/12)*365.2425*60*60*24)
1.0

Как отмечено выше, используйте to_datetime, чтобы избежать этого.

2 голосов
/ 23 октября 2019

Проблема с преобразованием месяцев, здесь используется 'rounded' год (потому что високосный год) и делится на 12 для 'rounded' месяца:

print (pd.to_timedelta(365.2425, unit='d') / 12)
30 days 10:29:06

print (pd.to_timedelta(1, unit='M'))
30 days 10:29:06

print (pd.to_timedelta(df['mo']-1,unit='M'))
0   243 days 11:52:48
1   243 days 11:52:48
Name: mo, dtype: timedelta64[ns]

Лучшее решение - использовать to_datetime с year, monht и day столбцами и при необходимости отфильтруйте его по подмножеству с list(d.values()) (если в реальных данных есть другие столбцы):

d = {'yr':'year', 'mo':'month', 'dy':'day'}
df['dtime'] = pd.to_datetime(df.rename(columns=d)[list(d.values())])

print (df)
     yr  mo  dy      dtime
0  2019   9  25 2019-09-25
1  2019   9  26 2019-09-26
...