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を使用しています。
日時は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がこれまで持っていた不足を回避しているようです。
私は次のトリックが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
これを行うにはもっと簡単な方法があるはずですが、あなたがしようとしていることに応じて、最良のルートは通常の 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+
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)
Numpy 1.7(datetimeがまだ実験的としてラベル付けされている場合)にアップグレードする場合、以下が動作するはずです。
dates/np.timedelta64(1,'Y')
アノンの答え 私にとってはうまくいきますが、days
のステートメントを変更するだけです
から:
days = dates - dates.astype('datetime64[M]') + 1
に:
days = dates.astype('datetime64[D]') - dates.astype('datetime64[M]') + 1
別の可能性は次のとおりです。
np.datetime64(dates,'Y') - returns - numpy.datetime64('2010')
または
np.datetime64(dates,'Y').astype(int)+1970 - returns - 2010
しかし、スカラー値でのみ機能し、配列を取りません
これが私のやり方です。
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がこの機能をサポートしたいなら、アプリケーション開発では常に必要です。このように自分のものを転がさなければならないとき、私はいつも非常に緊張します、私はいつも私がエッジケースを見逃しているように感じます。
残念ながら、それを行う直接的な方法はまだありませんが、間接的な方法がいくつかあります。
[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番目のものにはもう少し注意する必要があるかもしれません。