2017-12-14 3 views
1

저는 UTC 시간과 시간대에 대한 열을 포함하는 대형 판다 데이터 프레임 (수천만 행)이 있습니다. 이 두 개의 다른 열을 기반으로 행의 로컬 시간을 포함하는 열을 만들고 싶습니다.팬더 데이터 프레임의 시간대를 효율적으로 변환합니다.

내 원래의 시도 I가 테스트 한 작은 샘플에 근무하지만, 매우 느립니다 전체 데이터에서 작동하도록 충분하지 않습니다 df.apply 사용되었다

df['LoginTimeLocal'] = \ 
    df.apply(lambda row: row.LoginTimeUtc.tz_localize('UTC').tz_convert(row.TimeZoneCode)) 

이것은 결과를 시간대 정보가 포함 된 현지 시간으로 날짜 시간을 포함하는 새 열이 추가되었습니다.

나는 비슷한 것을하기위한 효율적이고 벡터화 된 방법을 제공하는 this 답을 찾았습니다. 이 코드를 다시 작성하여 원하는대로 처리했지만 새로운 열에는 동일한 시간대 (또는 시간대 정보가없는 날짜) 만 포함 된 경우에만 작동하는 것처럼 보입니다. 여기에 내 코드입니다 : 나는 단지 하나 개의 시간대 (즉, len(df.TimeZoneCode.unique()) = 1)에서 날짜가 들어있는 데이터의 샘플에서이 작업을 실행하면

# localize all utc dates 
df['LoginTimeUtc'] = df['LoginTimeUtc'].dt.tz_localize('UTC') 

# initialize LoginTimeLocal column (probably not necessary) 
df['LoginTimeLocal'] = df['LoginTimeUtc'] 

# for every time zone in the data 
for tz in df.TimeZoneCode.unique(): 
    mask = (df.TimeZoneCode == tz) 

    # make entries in a new column with converted timezone 
    df.loc[mask, 'LoginTimeLocal'] = \ 
     df.loc[mask,'LoginTimeLocal'].dt.tz_convert(tz) 

, 그것을 잘 작동합니다. 데이터 프레임에 두 개 이상의 시간대가있는 즉시 ValueError: incompatible or non tz-aware value이 표시됩니다.

여기에 어떤 문제가 발생하는지 누구든지 볼 수 있습니까?

답변

1

데모 :

소스 DF :

In [11]: df 
Out[11]: 
      datetime   time_zone 
0 2016-09-19 01:29:13 America/Bogota 
1 2016-09-19 02:16:04 America/New_York 
2 2016-09-19 01:57:54  Africa/Cairo 
3 2016-09-19 11:00:00 America/Bogota 
4 2016-09-19 12:00:00 America/New_York 
5 2016-09-19 13:00:00  Africa/Cairo 

해결 방법 : 타임 스탬프를 변환 할 때

In [12]: df['new'] = df.groupby('time_zone')['datetime'] \ 
         .transform(lambda x: x.dt.tz_localize(x.name)) 

In [13]: df 
Out[13]: 
      datetime   time_zone     new 
0 2016-09-19 01:29:13 America/Bogota 2016-09-19 06:29:13 
1 2016-09-19 02:16:04 America/New_York 2016-09-19 06:16:04 
2 2016-09-19 01:57:54  Africa/Cairo 2016-09-18 23:57:54 
3 2016-09-19 11:00:00 America/Bogota 2016-09-19 16:00:00 
4 2016-09-19 12:00:00 America/New_York 2016-09-19 16:00:00 
5 2016-09-19 13:00:00  Africa/Cairo 2016-09-19 11:00:00 
+0

이 나를 위해 – timleathart

+0

@timleathart을 앞에'NonExistentTimeError'을 제공, 일반적으로 그런 일이 겨울에서 여름 시간으로 전환 할 때 1 시간 점프 때문에 존재하지 않는 ... – MaxU

관련 문제