0
0

numpy.datetime64と別形式の相互変換

Last updated at Posted at 2024-06-20

はじめに

numpyでの日付処理は速度を最優先にするためpandasやdatetimeと異なった形式で格納される。
https://numpy.org/doc/stable/reference/arrays.datetime.html
公式サイトを見るとわかる通り、Unix時間を単位[s or msなど]に応じて整数で格納される。
msの場合はUnix時間の秒数を1000倍にして整数にして格納する。
もちろんタイムゾーンもつけない。
numpy.datetime64に変換する際はタイムゾーンを外して行う必要がある。今のところエラーにはならないが、非推奨。

タイムゾーン付文字列(ISO 8601形式)からnumpy.datetime64に変換する

import datetime

import numpy as np

dateList = ['2021-01-01T12:00:00Z', '2021-01-02T12:00:00Z', '2021-07-02T12:00:00+09:00']
datetimeList = [datetime.datetime.fromisoformat(date).astimezone(tz=datetime.UTC).replace(tzinfo=None) for date in dateList]
datetimeList = np.array(datetimeList, dtype='datetime64[s]')
print(datetimeList)  # ['2021-01-01T12:00:00' '2021-01-02T12:00:00' '2021-07-02T03:00:00']

このようにastimezoneメソッドを使用して使用するタイムゾーンに変換して、replaceメソッドを使用してタイムゾーンを外して変換する。

datatime.datetimeからnumpy.datetime64に変換する

上記の例に含まれるので割愛

numpy.datetime64からタイムゾーン付文字列(ISO 8601形式)に変換

import datetime
import time

import numpy as np

dateList = ['2021-01-01T12:00:00Z', '2021-01-02T12:00:00Z', '2021-07-02T12:00:00Z']
datetimeList = [datetime.datetime.fromisoformat(date).astimezone(tz=datetime.UTC).replace(tzinfo=None) for date in dateList]
datetimeList = np.array(datetimeList, dtype='datetime64[s]')
print(datetimeList)  # ['2021-01-01T12:00:00' '2021-01-02T12:00:00' '2021-07-02T12:00:00']

# 方法1: numpy.datetime64[s]をstr関数で文字列化してZをつける
timeA = time.time()
for i in range(100000):
    datetimeStrList = [str(datetime)+'Z' for datetime in datetimeList]
timeB = time.time()
print(timeB-timeA)  # 0.2197432518005371

# 方法2: numpy.datetime64[s]を.astype('str')で文字列化してZをつける
timeA = time.time()
for i in range(100000):
    datetimeStrList = [string+'Z' for string in datetimeList.astype('str')]
timeB = time.time()
print(timeB-timeA)  # 0.4033396244049072

# 方法3: numpy.datetime64[s]を.astype(np.float64)でunix時間に変換し、datetimeにして文字列に直す。
timeA = time.time()
for i in range(100000):
    strList = [datetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC).strftime('%Y-%m-%dT%H:%M:%SZ')
               for timestamp in datetimeList.astype(np.float64)]
timeB = time.time()
print(timeB-timeA)  # 1.1203858852386475

方法2,3は配列の操作が2回発生し、時間がかかるので方法1で行うほうが良い。
方法3の場合はnumpy.datetime64[s]で格納されているものを使わないといけない。単位がmsだと値が1000倍違うためである。numpyのデフォルトの格納単位はmsなので特に注意が必要である。

numpy.datetime64からdatatime.datetimeに変換

import datetime

import numpy as np

dateList = ['2021-01-01T12:00:00Z', '2021-01-02T12:00:00Z', '2021-07-02T12:00:00Z']
datetimeList = [datetime.datetime.fromisoformat(date).astimezone(tz=datetime.UTC).replace(tzinfo=None) for date in dateList]
datetimeList = np.array(datetimeList, dtype='datetime64[s]')
print(datetimeList)  # ['2021-01-01T12:00:00' '2021-01-02T12:00:00' '2021-07-02T12:00:00']

datetimeList = [datetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC) for timestamp in datetimeList.astype(np.float64)]
print(datetimeList)

datetimeList.astype(np.float64)により、整数のみ(ここではUNIX時間)を抜き出す。それからdatetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC)によりdatetime.datetimeに変換する。タイムゾーンをつけたい場合はtzに必要なタイムゾーンを入れ、つけない場合はNoneにする。
ここでもnumpy.datetime64[s]で格納されているか注意する。そうでなければいったん変換する。

参考

公式サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0