web-dev-qa-db-ja.com

numpy datetime64から年、月、または日を取得する

Datetime64型の配列があります。

dates = np.datetime64(['2010-10-17', '2011-05-13', "2012-01-15"])

Np.array of yearsを取​​得するために各要素をループするよりも良い方法はありますか?

years = f(dates)
#output:
array([2010, 2011, 2012], dtype=int8) #or dtype = string

安定したnumpyバージョン1.6.2を使用しています。

50
enedene

日時はnumpyでは安定していないため、pandasをこれに使用します:

In [52]: import pandas as pd

In [53]: dates = pd.DatetimeIndex(['2010-10-17', '2011-05-13', "2012-01-15"])

In [54]: dates.year
Out[54]: array([2010, 2011, 2012], dtype=int32)

Pandasは内部でnumpy datetimeを使用しますが、numpyがこれまで持っていた不足を回避しているようです。

36
bmu

私は次のトリックが2倍から4倍の速度の増加に対して、pandas上記のメソッド(つまりpd.DatetimeIndex(dates).yearなど))を与えることを発見しました。[dt.year for dt in dates.astype(object)]の速度pandasメソッドに似ています。また、これらのトリックは、任意の形状(2D、3Dなど)のndarrayに直接適用できます。

dates = np.arange(np.datetime64('2000-01-01'), np.datetime64('2010-01-01'))
years = dates.astype('datetime64[Y]').astype(int) + 1970
months = dates.astype('datetime64[M]').astype(int) % 12 + 1
days = dates - dates.astype('datetime64[M]') + 1
23
Anon

これを行うにはもっと簡単な方法があるはずですが、あなたがしようとしていることに応じて、最良のルートは通常の Python datetimeオブジェクト に変換することです。

datetime64Obj = np.datetime64('2002-07-04T02:55:41-0700')
print datetime64Obj.astype(object).year
# 2002
print datetime64Obj.astype(object).day
# 4

以下のコメントに基づいて、これはPython 2.7.xおよびPython 3.6+

8
Nick

Numpyバージョン1.10.4およびpandasバージョン0.17.1を使用して、

dates = np.array(['2010-10-17', '2011-05-13', '2012-01-15'], dtype=np.datetime64)
pd.to_datetime(dates).year

あなたが探しているものが手に入ります:

array([2010, 2011, 2012], dtype=int32)
2
Steve Schulist

Numpy 1.7(datetimeがまだ実験的としてラベル付けされている場合)にアップグレードする場合、以下が動作するはずです。

dates/np.timedelta64(1,'Y')
1
Daniel

アノンの答え 私にとってはうまくいきますが、daysのステートメントを変更するだけです

から:

days = dates - dates.astype('datetime64[M]') + 1

に:

days = dates.astype('datetime64[D]') - dates.astype('datetime64[M]') + 1
0
user3648119

別の可能性は次のとおりです。

np.datetime64(dates,'Y') - returns - numpy.datetime64('2010')

または

np.datetime64(dates,'Y').astype(int)+1970 - returns - 2010

しかし、スカラー値でのみ機能し、配列を取りません

0
Mark

これが私のやり方です。

import numpy as np

def dt2cal(dt):
    """
    Convert array of datetime64 to a calendar array of year, month, day, hour,
    minute, seconds, microsecond with these quantites indexed on the last axis.

    Parameters
    ----------
    dt : datetime64 array (...)
        numpy.ndarray of datetimes of arbitrary shape

    Returns
    -------
    cal : uint32 array (..., 7)
        calendar array with last axis representing year, month, day, hour,
        minute, second, microsecond
    """

    # allocate output 
    out = np.empty(dt.shape + (7,), dtype="u4")
    # decompose calendar floors
    Y, M, D, h, m, s = [dt.astype(f"M8[{x}]") for x in "YMDhms"]
    out[..., 0] = Y + 1970 # Gregorian Year
    out[..., 1] = (M - Y) + 1 # month
    out[..., 2] = (D - M) + 1 # dat
    out[..., 3] = (dt - D).astype("m8[h]") # hour
    out[..., 4] = (dt - h).astype("m8[m]") # minute
    out[..., 5] = (dt - m).astype("m8[s]") # second
    out[..., 6] = (dt - s).astype("m8[us]") # microsecond
    return out

任意の入力次元でベクトル化され、高速で直感的で、numpy v1.15.4で動作し、パンダを使用しません。

I 本当に numpyがこの機能をサポートしたいなら、アプリケーション開発では常に必要です。このように自分のものを転がさなければならないとき、私はいつも非常に緊張します、私はいつも私がエッジケースを見逃しているように感じます。

0
RBF06

残念ながら、それを行う直接的な方法はまだありませんが、間接的な方法がいくつかあります。

[dt.year for dt in dates.astype(object)]

または

[datetime.datetime.strptime(repr(d), "%Y-%m-%d %H:%M:%S").year for d in dates]

両方とも例に触発された here

Numpy 1.6.1ではこれらの両方が機能します。 datetime64のrepr()には小数点の後に小数部が含まれる可能性があるため、2番目のものにはもう少し注意する必要があるかもしれません。

0
acjay