Панды, не признающие TZ, знают дату и время - PullRequest
0 голосов
/ 04 июля 2018

Я пытаюсь написать скрипт, который принимает дату и возвращает фрейм данных pandas, содержащий нули с локализованными датами в полчаса для индекса. SP относится к расчетному периоду, который составляет полчаса. Сценарии работают очень хорошо в большинстве дней, но когда они переходят на летнее время или наоборот, я получаю:

AmbiguousTimeError: Невозможно определить время dst от «2017-10-29 01:00:00», попробуйте использовать аргумент «неоднозначный»

Это происходит в строке:

df_datetime.at[datetime, "Generation"] = 0

Дата, которую он пытается преобразовать, - «2017-10-29 01:00:00», даже если ему дается «2017-10-29 01:00:00 + 1:00:00». преобразовать в UTC = 0, преобразовать в панд, затем снова локализовать? 29 октября 2017 года в Великобритании закончился переход на летнее время.

Полный сценарий приведен ниже:

import pandas as pd
from datetime import datetime, timedelta
import pytz


def SP_to_time_delta(SP):
    dec_hour = (SP - 1)/2

    hour = int(dec_hour)
    if abs(int(dec_hour)-dec_hour) == 0.5:
        minute = 30
    else:
        minute = 0

    SP_timedelta = timedelta(hours=hour, minutes=minute)
    return SP_timedelta

def localize_datetime_UK(date, SP):
    pytz_tz = pytz.timezone('Europe/London')
    local_date = pytz_tz.localize(date)
    SP_timedelta = SP_to_time_delta(SP)

    local_datetime = local_date+SP_timedelta
    return local_datetime    

def get_datetime_df(SettlementDate, max_SP):
    df_datetime = pd.DataFrame([])
    for i in range(max_SP+1):
        datetime = localize_datetime_UK(SettlementDate, i)
        df_datetime.at[datetime, "Generation"] = 0
    df_datetime = df_datetime.sort_index()
    return df_datetime    

SettlementDate = datetime(2017, 10, 29) 
df_datetime = get_datetime_df(SettlementDate, 50)   

Какой лучший способ решить эту проблему?

Спасибо за все ответы и помощь!

1 Ответ

0 голосов
/ 04 июля 2018

Ваша проблема возникает из-за путаницы в летнее время. Учтите следующее:

import pandas as pd
from datetime import datetime, timedelta
import pytz

pytz_tz = pytz.timezone('Europe/London')

datetime_1 = pytz_tz.localize(datetime(2017, 10, 29) \
             + timedelta(hours=0, minutes=0))
datetime_2 = pytz_tz.localize(datetime(2017, 10, 29) \
             + timedelta(hours=1, minutes=0))

print(datetime_1)
print(datetime_2)

> 2017-10-29 00:00:00+01:00
> 2017-10-29 01:00:00+00:00

Как видите, вы обрабатываете в два раза «один и тот же» момент времени, но с разными кодировками.

Одним из решений может быть преобразование всех времен в UTC (у которого нет dst) и преобразование времен назад только при необходимости для вывода.

Тем не менее, я думаю, что вы добавляете timedelta в неправильном месте. Рассмотрим

datetime_1 = pytz_tz.localize(datetime(2017, 10, 29)) \  # localize first
             + timedelta(hours=0)  # then add the delta
datetime_2 = pytz_tz.localize(datetime(2017, 10, 29)) \ # localize first
             + timedelta(hours=1)  # then add the delta

> 2017-10-29 00:00:00+01:00
> 2017-10-29 01:00:00+01:00

, который дает уникальные результаты. Проверьте семантику вашего приложения, какая версия применяется.

===== старый ответ ======

Вы должны сделать так, чтобы часовой пояс объекта datetime был известен с помощью

from datetime import datetime, timedelta
from pytz import timezone
import pytz

eastern = timezone('US/Eastern')
SelltementDate = eastern.localize(datetime(2017, 10, 29, 0, 0, 0))

См. Также документацию pytz .

.
...