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

#python #pandas #datetime

Вопрос:

Вот моя структура данных:

 ids = 1
timezones = ['America/Los_Angeles', 'Europe/Paris', 'America/New_York']
utc_time = ['2020-09-03 19:36:18.534', '2020-09-03 19:36:18.534', '2020-09-03 19:36:18.534']

df = pd.DataFrame({'id':ids,
                   'timezone':timezones,
                   'utc_time':utc_time})
print(df)

   id             timezone                 utc_time
0   1  America/Los_Angeles  2020-09-03 19:36:18.534
1   1         Europe/Paris  2020-09-03 19:36:18.534
2   1     America/New_York  2020-09-03 19:36:18.534
 

Как я могу создать новый столбец, добавленный в этот фрейм данных, который преобразует время UTC в местное время в зависимости от часового пояса? Я попробовал несколько найденных решений, но не смог заставить их работать в этом формате, когда часовой пояс меняется для каждой строки.

Заранее спасибо.

Ответ №1:

Это пример, когда я должен использовать .apply сквозные строки, чтобы получить то, что вам нужно.

Основными шагами являются:

  1. преобразуйте свои данные в метки времени
  2. локализовать в UTC
  3. преобразование строки за строкой
 import pandas

ids = 1
timezones = ['America/Los_Angeles', 'Europe/Paris', 'America/New_York']
datestrings = ['2020-09-03 19:36:18.534', '2020-09-03 19:36:18.534', '2020-09-03 19:36:18.534']

df = pandas.DataFrame({
    'id': ids,
    'timezone': timezones,
    'datestring': datestrings
}).assign(
    # steps 1 amp; 2:
    utc_time=lambda df: pandas.to_datetime(df["datestring"]).dt.tz_localize("UTC"),
    # step 3:
    local_time=lambda df: df.apply(lambda r: r["utc_time"].tz_convert(r["timezone"]), axis=1)
)
 
 
 id             timezone               datestring                         utc_time                        local_time
  1  America/Los_Angeles  2020-09-03 19:36:18.534 2020-09-03 19:36:18.534000 00:00  2020-09-03 12:36:18.534000-07:00
  1         Europe/Paris  2020-09-03 19:36:18.534 2020-09-03 19:36:18.534000 00:00  2020-09-03 21:36:18.534000 02:00
  1     America/New_York  2020-09-03 19:36:18.534 2020-09-03 19:36:18.534000 00:00  2020-09-03 15:36:18.534000-04:00
 

Ответ №2:

 from dateutil import tz
from datetime import datetime
import pandas as pd
def convert(row):
    from_zone = tz.gettz('UTC')
    to_zone = tz.gettz(row['timezone'])
    utc = datetime.strptime(row['utc_time'], '%Y-%m-%d %H:%M:%S.%f')
    utc = utc.replace(tzinfo=from_zone)
    target = utc.astimezone(to_zone)
    return target.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
data = {'id': [1, 1, 1], 'timezone': ['America/Los_Angeles', 'Europe/Paris', 'America/New_York'], 'utc_time': ['2020-09-03 19:36:18.534', '2020-09-03 19:36:18.534', '2020-09-03 19:36:18.534']}
df = pd.DataFrame(data=data)
df['local_time'] = df.apply(lambda row: convert(row), axis=1)
print(df)
 

Результат таков.

    id             timezone             utc_time           local_time
0   1  America/Los_Angeles  2020-09-03 19:36:18.534  2020-09-03 12:36:18.534
1   1         Europe/Paris  2020-09-03 19:36:18.534  2020-09-03 21:36:18.534
2   1     America/New_York  2020-09-03 19:36:18.534  2020-09-03 15:36:18.534