Примените лямбда-функцию к отметке времени, чтобы отрегулировать бессмысленное смещение

У меня есть «страницы» фрейма данных с полем метки времени «Dimension3». Dimension3 должен быть временем ISO, но есть некоторые бессмысленные смещения, вызывающие проблемы.

Фрейм данных - это просмотры страниц веб-сайта посетителями со всего мира, поэтому каждая строка имеет собственную метку времени и смещение часового пояса.

Смещение для времени ISO должно быть в пределах от -12 до +14.

Большинство моих отметок времени попадают в этот диапазон. Вот пример звуковой точки данных:

x = dateutil.parser.parse('2019-11-11T07:08:09.640-4:00')
x
datetime.datetime(2019, 11, 11, 7, 8, 9, 640000, tzinfo=tzoffset(None, -14400))

Вот пример проблемной точки данных, которая появляется в моем фрейме данных:

y = dateutil.parser.parse('2019-11-11T07:08:09.640-31:00')
y
datetime.datetime(2019, 11, 11, 7, 8, 9, 640000, tzinfo=tzoffset(None, -111600))

Проблемный имеет смещение -31, что больше минимальной границы -12.

Это проблематично, потому что, когда я пытаюсь отправить эти данные в базу данных postgres с типом поля timestamptz, я получаю сообщение об ошибке, что данные не удалось загрузить из-за того, что некоторые точки данных вышли за допустимые границы.

Я потратил немного времени на изучение ответов на это сообщение и

person Doug Fir    schedule 15.12.2019    source источник
comment
Разве не имеет смысла исправить проблему в восходящем направлении: предотвратить создание таких бессмысленных временных меток в первую очередь. Часовой пояс - это не только разница со временем в формате UTC: часовой пояс может иногда изменять смещение, поскольку страна может решить это изменить.   -  person Willem Van Onsem    schedule 15.12.2019
comment
Мы не можем заменить данные из API задним числом, и это выходит за рамки моей непосредственной задачи по передаче этих данных в Postgres. Это также крошечное меньшинство точек данных.   -  person Doug Fir    schedule 15.12.2019
comment
Абсолютный резервный вариант - это преобразование поля в строку с последующей загрузкой в ​​postgres, но я действительно хочу избежать этого   -  person Doug Fir    schedule 15.12.2019
comment
Я нашел эту процедуру, которая преобразуется в местный часовой пояс, если мы сможем выяснить, как вывести часовой пояс, это может сработать для того, что вы делаете: def utc_to_local (utc_dt): return utc_dt.replace (tzinfo = timezone.utc) .astimezone (tz = Нет) Я все еще изучаю это, меня тоже интересует ответ   -  person oppressionslayer    schedule 15.12.2019
comment
Спасибо за вашу помощь. Я пытаюсь найти способ определить временные метки проблемы, чтобы применить эту функцию к   -  person Doug Fir    schedule 15.12.2019
comment
@DavisHerring большинство временных меток являются звуковыми и содержат смещение часового пояса относительно UTC. Таким образом, они означают, что просмотр страницы нашего веб-сайта имел место в любое время и с любым смещением часового пояса. Для тех временных меток небольшого меньшинства с офсетами, выходящими за пределы допустимого диапазона смещения часового пояса -12, +14, я хотел бы установить его на минимальное или максимальное, -12 или +14, в зависимости от того, положительное или отрицательное смещение.   -  person Doug Fir    schedule 15.12.2019
comment
@DougFir: Ты действительно так сказал, извини. Покажите код, который вы пробовали для функции регулировки.   -  person Davis Herring    schedule 15.12.2019
comment
@DavisHerring это то, что я использую прямо сейчас. Я просто полностью отбрасываю смещение, потому что не знаю, как определить, выходит ли смещение за границы: pages['dimension3'] = pages['dimension3'].apply(lambda x: x.replace(tzinfo = None))   -  person Doug Fir    schedule 15.12.2019
comment
В идеальном мире я бы использовал эту лямбда-функцию только вместе с предложением if, где, если смещение меньше 12, установите его ровно на 12, а если больше 14, установите его ровно на 14. Я не знаю, как это проверить. и сбросить смещения таким образом   -  person Doug Fir    schedule 15.12.2019
comment
Я думаю, что это решение вполне подходит для вашей проблемы (просто вручную преобразуйте его в GMT): stackoverflow.com/a/38992733/11610186   -  person Grzegorz Skibinski    schedule 15.12.2019
comment
@DougFir: не могли бы вы просто проконсультироваться с utcoffset в лямбда-выражении и вычислить на его основе новый объект timezone (когда не просто повторно использовать ввод, потому что он действителен)?   -  person Davis Herring    schedule 15.12.2019


Ответы (1)


Я использовал пользовательскую функцию с помощью try, кроме лямбда:

def rogue_tz_offsets(t):
    """
    try to convert to timestamp and if it fails remove timezone offset
    """
    t = dateutil.parser.parse(t)
    try:
        return t.isoformat()
    except:
        t = t.replace(tzinfo = None)
        return t.isoformat()

А потом

pages['dimension3'] = pages['dimension3'].apply(lambda x: rogue_tz_offsets(x))
person Doug Fir    schedule 16.12.2019