web-dev-qa-db-ja.com

Datetime、Timestamp、およびdatetime64の間の変換

numpy.datetime64オブジェクトをdatetime.datetime(またはTimestamp)に変換するにはどうすればいいですか?

次のコードでは、datetime、timestamp、およびdatetime64の各オブジェクトを作成します。

import datetime
import numpy as np
import pandas as pd
dt = datetime.datetime(2012, 5, 1)
# A strange way to extract a Timestamp object, there's surely a better way?
ts = pd.DatetimeIndex([dt])[0]
dt64 = np.datetime64(dt)

In [7]: dt
Out[7]: datetime.datetime(2012, 5, 1, 0, 0)

In [8]: ts
Out[8]: <Timestamp: 2012-05-01 00:00:00>

In [9]: dt64
Out[9]: numpy.datetime64('2012-05-01T01:00:00.000000+0100')

注:タイムスタンプから日時を取得するのは簡単です。 /

In [10]: ts.to_datetime()
Out[10]: datetime.datetime(2012, 5, 1, 0, 0)

しかしnumpy.datetime64dt64)からdatetimeまたはTimestampをどのように抽出するのでしょうか。

更新:私のデータセットのやや厄介な例(おそらくやる気を起こさせる例)は、次のように思われる。

dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100')

これはdatetime.datetime(2002, 6, 28, 1, 0)であるべきで、長い(!)ではありません(1025222400000000000L)...

230
Andy Hayden

numpy.datetime64numpy-1.8のUTCでの時間を表すdatetimeオブジェクトに変換するには、次のようにします。

>>> from datetime import datetime
>>> import numpy as np
>>> dt = datetime.utcnow()
>>> dt
datetime.datetime(2012, 12, 4, 19, 51, 25, 362455)
>>> dt64 = np.datetime64(dt)
>>> ts = (dt64 - np.datetime64('1970-01-01T00:00:00Z')) / np.timedelta64(1, 's')
>>> ts
1354650685.3624549
>>> datetime.utcfromtimestamp(ts)
datetime.datetime(2012, 12, 4, 19, 51, 25, 362455)
>>> np.__version__
'1.8.0.dev-7b75899'

上記の例では、単純なdatetimeオブジェクトがnp.datetime64によってUTCの時刻として解釈されると仮定しています。


Datetimeをnp.datetime64に変換して戻す(numpy-1.6)には

>>> np.datetime64(datetime.utcnow()).astype(datetime)
datetime.datetime(2012, 12, 4, 13, 34, 52, 827542)

これは単一のnp.datetime64オブジェクトとnp.datetime64の配列の両方に対して機能します。

Np.datetime64をnp.int8、np.int16などと同じように考えて、int、datetime、対応するnumpyオブジェクトなどのPythonオブジェクト間の変換に同じメソッドを適用します。

あなたの「厄介な例」は正しく機能します。

>>> from datetime import datetime
>>> import numpy 
>>> numpy.datetime64('2002-06-28T01:00:00.000000000+0100').astype(datetime)
datetime.datetime(2002, 6, 28, 0, 0)
>>> numpy.__version__
'1.6.2' # current version available via pip install numpy

次のようにインストールされたnumpy-1.8.0longの値を再現できます。

pip install git+https://github.com/numpy/numpy.git#Egg=numpy-dev

同じ例

>>> from datetime import datetime
>>> import numpy
>>> numpy.datetime64('2002-06-28T01:00:00.000000000+0100').astype(datetime)
1025222400000000000L
>>> numpy.__version__
'1.8.0.dev-7b75899'

numpy.datetime64型の.astype(datetime)は、numpy-1.8上でPython整数(long)を返す.astype(object)と同等であるため、longを返します。

日時オブジェクトを取得するには、次のようにします。

>>> dt64.dtype
dtype('<M8[ns]')
>>> ns = 1e-9 # number of seconds in a nanosecond
>>> datetime.utcfromtimestamp(dt64.astype(int) * ns)
datetime.datetime(2002, 6, 28, 0, 0)

秒を直接使用するdatetime64を取得するには

>>> dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100', 's')
>>> dt64.dtype
dtype('<M8[s]')
>>> datetime.utcfromtimestamp(dt64.astype(int))
datetime.datetime(2002, 6, 28, 0, 0)

派手なドキュメント datetime APIは実験的なものであり、将来の派手なバージョンでは変更される可能性があると言っています。

106
jfs

あなただけのpd.Timestampコンストラクタを使用することができます。次の図は、これと関連する質問に役立ちます。

Conversions between time representations

167
Quant

地獄へようこそ。

Datetime64オブジェクトをpandas.Timestampに渡すだけです。

In [16]: Timestamp(numpy.datetime64('2012-05-01T01:00:00.000000'))
Out[16]: <Timestamp: 2012-05-01 01:00:00>

私はNumPy 1.6.1でもこれがうまくいかないことに気づいた。

numpy.datetime64('2012-05-01T01:00:00.000000+0100')

また、pandas.to_datetimeを使用することができます(これはdevバージョンからは外れています、v0.9.1をチェックしていません):

In [24]: pandas.to_datetime('2012-05-01T01:00:00.000000+0100')
Out[24]: datetime.datetime(2012, 5, 1, 1, 0, tzinfo=tzoffset(None, 3600))
111
Wes McKinney

私は、Pythonのdatetimeモジュール、numpyのdatetime64/timedelta64、およびパンダのTimestamp/Timedeltaオブジェクトの間の関係をよりよく説明するために、より統合された努力があるかもしれないと思う。

Pythonの日時標準ライブラリ

日時標準ライブラリには4つの主な目的があります。

  • 時間 - 時間、分、秒、マイクロ秒で測定された時間のみ
  • 日付 - 年、月、日のみ
  • datetime - 時間と日付のすべての構成要素
  • timedelta - 最大日数単位の時間

これら4つのオブジェクトを作成する

>>> import datetime
>>> datetime.time(hour=4, minute=3, second=10, microsecond=7199)
datetime.time(4, 3, 10, 7199)

>>> datetime.date(year=2017, month=10, day=24)
datetime.date(2017, 10, 24)

>>> datetime.datetime(year=2017, month=10, day=24, hour=4, minute=3, second=10, microsecond=7199)
datetime.datetime(2017, 10, 24, 4, 3, 10, 7199)

>>> datetime.timedelta(days=3, minutes = 55)
datetime.timedelta(3, 3300)

>>> # add timedelta to datetime
>>> datetime.timedelta(days=3, minutes = 55) + \
    datetime.datetime(year=2017, month=10, day=24, hour=4, minute=3, second=10, microsecond=7199)
datetime.datetime(2017, 10, 27, 4, 58, 10, 7199)

NumPyのdatetime64およびtimedelta64オブジェクト

NumPyには個別の日付と時刻のオブジェクトはなく、単一の瞬間を表す単一のdatetime64オブジェクトがあります。 datetimeモジュールのdatetimeオブジェクトは、マイクロ秒の精度(100万分の1秒)を持ちます。 NumPyのdatetime64オブジェクトを使うと、数時間からアト秒(10 ^ -18)までの精度を設定できます。コンストラクタはより柔軟で、さまざまな入力を取ります。

NumPyのdatetime64とtimedelta64オブジェクトを構築する

単位に文字列を含む整数を渡します。 ここにすべてのユニットを見なさい 。それはUNIXエポックの後にその多くの単位に変換されます:1970年1月1日

>>> np.datetime64(5, 'ns') 
numpy.datetime64('1970-01-01T00:00:00.000000005')

>>> np.datetime64(1508887504, 's')
numpy.datetime64('2017-10-24T23:25:04')

ISO 8601形式であれば、文字列を使用することもできます。

>>> np.datetime64('2017-10-24')
numpy.datetime64('2017-10-24')

タイムデルタは単一の単位を持ちます

>>> np.timedelta64(5, 'D') # 5 days
>>> np.timedelta64(10, 'h') 10 hours

2つのdatetime64オブジェクトを減算してそれらを作成することもできます

>>> np.datetime64('2017-10-24T05:30:45.67') - np.datetime64('2017-10-22T12:35:40.123')
numpy.timedelta64(147305547,'ms')

Pandas TimestampとTimedeltaはNumPyの上にさらに多くの機能を構築します

パンダのタイムスタンプは、日時と非常によく似ていますが、より多くの機能を備えています。あなたはpd.Timestamppd.to_datetimeのどちらかでそれらを構成することができます。

>>> pd.Timestamp(1239.1238934) #defautls to nanoseconds
Timestamp('1970-01-01 00:00:00.000001239')

>>> pd.Timestamp(1239.1238934, unit='D') # change units
Timestamp('1973-05-24 02:58:24.355200')

>>> pd.Timestamp('2017-10-24 05') # partial strings work
Timestamp('2017-10-24 05:00:00')

pd.to_datetimeは、(もう少しオプションがありますが)非常によく似た働きをし、文字列のリストをタイムスタンプに変換できます。

>>> pd.to_datetime('2017-10-24 05')
Timestamp('2017-10-24 05:00:00')

>>> pd.to_datetime(['2017-1-1', '2017-1-2'])
DatetimeIndex(['2017-01-01', '2017-01-02'], dtype='datetime64[ns]', freq=None)

Pythonのdatetimeをdatetime64とTimestampに変換する

>>> dt = datetime.datetime(year=2017, month=10, day=24, hour=4, 
                   minute=3, second=10, microsecond=7199)
>>> np.datetime64(dt)
numpy.datetime64('2017-10-24T04:03:10.007199')

>>> pd.Timestamp(dt) # or pd.to_datetime(dt)
Timestamp('2017-10-24 04:03:10.007199')

派手なdatetime64からdatetimeおよびTimestampへの変換

>>> dt64 = np.datetime64('2017-10-24 05:34:20.123456')
>>> unix_Epoch = np.datetime64(0, 's')
>>> one_second = np.timedelta64(1, 's')
>>> seconds_since_Epoch = (dt64 - unix_Epoch) / one_second
>>> seconds_since_Epoch
1508823260.123456

>>> datetime.datetime.utcfromtimestamp(seconds_since_Epoch)
>>> datetime.datetime(2017, 10, 24, 5, 34, 20, 123456)

タイムスタンプに変換

>>> pd.Timestamp(dt64)
Timestamp('2017-10-24 05:34:20.123456')

タイムスタンプからdatetimeおよびdatetime64への変換

パンダのタイムスタンプは非常に強力なので、これは非常に簡単です。

>>> ts = pd.Timestamp('2017-10-24 04:24:33.654321')

>>> ts.to_pydatetime()   # Python's datetime
datetime.datetime(2017, 10, 24, 4, 24, 33, 654321)

>>> ts.to_datetime64()
numpy.datetime64('2017-10-24T04:24:33.654321000')
63
Ted Petrou
>>> dt64.tolist()
datetime.datetime(2012, 5, 1, 0, 0)

DatetimeIndexの場合、tolistdatetimeオブジェクトのリストを返します。単一のdatetime64オブジェクトの場合は、単一のdatetimeオブジェクトを返します。

27
eumiro

パンダの一連の日時を通常のPythonの日時に変換したい場合は、.to_pydatetime()を使用することもできます。

pd.date_range('20110101','20110102',freq='H').to_pydatetime()

> [datetime.datetime(2011, 1, 1, 0, 0) datetime.datetime(2011, 1, 1, 1, 0)
   datetime.datetime(2011, 1, 1, 2, 0) datetime.datetime(2011, 1, 1, 3, 0)
   ....

タイムゾーンもサポートしています。

pd.date_range('20110101','20110102',freq='H').tz_localize('UTC').tz_convert('Australia/Sydney').to_pydatetime()

[ datetime.datetime(2011, 1, 1, 11, 0, tzinfo=<DstTzInfo 'Australia/Sydney' EST+11:00:00 DST>)
 datetime.datetime(2011, 1, 1, 12, 0, tzinfo=<DstTzInfo 'Australia/Sydney' EST+11:00:00 DST>)
....

_ note _ :Pandasシリーズを操作している場合は、シリーズ全体でto_pydatetime()を呼び出すことはできません。リスト内包表記かそれに似たものを使って、個々のdatetime64で.to_pydatetime()を呼び出す必要があります。

datetimes = [val.to_pydatetime() for val in df.problem_datetime_column]
10
fantabolous

1つの選択肢は、strを使用してからto_datetime(または同様のもの)を使用することです。

In [11]: str(dt64)
Out[11]: '2012-05-01T01:00:00.000000+0100'

In [12]: pd.to_datetime(str(dt64))
Out[12]: datetime.datetime(2012, 5, 1, 1, 0, tzinfo=tzoffset(None, 3600))

注: "offset-aware"になるため、dtと等しくありません

In [13]: pd.to_datetime(str(dt64)).replace(tzinfo=None)
Out[13]: datetime.datetime(2012, 5, 1, 1, 0)

これは洗練されていないようです。

更新:これは "厄介な例"を扱うことができます。

In [21]: dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100')

In [22]: pd.to_datetime(str(dt64)).replace(tzinfo=None)
Out[22]: datetime.datetime(2002, 6, 28, 1, 0)
8
Andy Hayden

この記事は4年間掲載されていますが、私はまだこの変換の問題に苦しんでいます - そのため、この問題はある意味で2017年もまだ活発です。ぎこちない文書が簡単な変換アルゴリズムを容易に提供しないことに少しショックを受けましたが、それはまた別の話です。

モジュールnumpydatetimeのみを含む変換を行う別の方法に遭遇しました。パンダをインポートする必要はないので、このような単純な変換のためにインポートするには多くのコードが必要になります。元のdatetime.datetime マイクロ秒単位 にある場合、datetime64.astype(datetime.datetime)datetime64オブジェクトを返すことに気付きました。他の単位は整数のタイムスタンプを返します。最初にマイクロ秒単位に変換しない限り、datetime64をナノ秒単位で使用するNetcdfファイルからのデータI/Oにモジュールxarrayを使用します。これが変換コードの例です。

import numpy as np
import datetime

def convert_datetime64_to_datetime( usert: np.datetime64 )->datetime.datetime:
    t = np.datetime64( usert, 'us').astype(datetime.datetime)
return t

それは私のマシン上でテストされた唯一のもので、最近の2017 Anacondaディストリビューションを備えたPython 3.6です。私はスカラー変換のみを見て、配列ベースの変換をチェックしていませんが、それは良いことだと思いますが。操作が意味を成しているかどうかを確認するために、派手なdatetime64ソースコードを調べたこともありません。

4
ndl303

私は数えきれないほどこの答えに戻ってきたので、Numpyのdatetime64の値をPythonのdatetimeの値に変換する簡単な小さなクラスをまとめることにしました。私はそれがそこに他の人を助けることを願っています。

from datetime import datetime
import pandas as pd

class NumpyConverter(object):
    @classmethod
    def to_datetime(cls, dt64, tzinfo=None):
        """
        Converts a Numpy datetime64 to a Python datetime.
        :param dt64: A Numpy datetime64 variable
        :type dt64: numpy.datetime64
        :param tzinfo: The timezone the date / time value is in
        :type tzinfo: pytz.timezone
        :return: A Python datetime variable
        :rtype: datetime
        """
        ts = pd.to_datetime(dt64)
        if tzinfo is not None:
            return datetime(ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second, tzinfo=tzinfo)
        return datetime(ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second)

私はこれを私の道具袋に入れておくつもりです、何かが私に再びそれを必要とするであろうということを何かが教えてくれます。

1
MikeyE

実際、これらの日時タイプはすべて困難であり、潜在的に問題がある可能性があります(タイムゾーン情報を注意深く追跡する必要があります)。ここに私がしたことがあります、私はそれの少なくとも一部が「設計によるものではない」ことを私が心配していると認めます。また、これは必要に応じてもう少しコンパクトにすることができます。 numpy.datetime64 dt_aから始めます。

dt_a

numpy.datetime64( '2015-04-24T23:11:26.270000-0700')

dt_a1 = dt_a.tolist()#は、UTCでdatetimeオブジェクトを生成しますが、tzinfoは含まれません。

dt_a1

datetime.datetime(2015、4、25、6、11、26、270000)

# now, make your "aware" datetime:

dt_a2 = datetime.datetime(* list(dt_a1.timetuple()[:6])+ [dt_a1.microsecond]、tzinfo = pytz.timezone( 'UTC'))

...そしてもちろん、それは必要に応じて1行に圧縮することができます。

0
yoder
import numpy as np
import pandas as pd 

def np64toDate(np64):
    return pd.to_datetime(str(np64)).replace(tzinfo=None).to_datetime()

この関数を使ってpythonsのネイティブなdatetimeオブジェクトを取得します

0
Crystal

いくつかの解決策は私にはうまくいきますが、numpyはいくつかのパラメータを廃止するでしょう。私にとってより良い解決策は、パンダのdatetimeとして日付を読み、パンダオブジェクトの年、月、日を明示的に削除することです。次のコードは最も一般的な状況で機能します。

def format_dates(dates):
    dt = pd.to_datetime(dates)
    try: return [datetime.date(x.year, x.month, x.day) for x in dt]    
    except TypeError: return datetime.date(dt.year, dt.month, dt.day)
0