2012-11-30 76 views
38

我datetime64类型的数组:获取年,月,日从numpy的datetime64

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

难道还有比通过每个元素循环只是为了让np.array年有更好的方式:

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

我正在使用稳定的numpy版本1.6.2。

+0

你的意思是,当你写“F(日期)”。 “f()”做什么? – MikeyE

回答

28

由于datetime不在numpy的稳定,我会用熊猫此:

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) 

熊猫使用numpy的日期时间内,但似乎避免了短缺,那numpy的有到现在。

+4

这给了我numpy 1.7.1和pandas 0.12.0的错误结果。但是,'系列(日期).apply(lambda x:x.month)'似乎工作。 – dmvianna

+0

这里没有问题,相同的版本。如果你真的得到错误的结果,你应该打开一个熊猫问题。 – bmu

+0

哦,我实际上使用了'pd.DatetimeIndex(np.datetime64(['2010-10-17','2011-05-13',“2012-01-15”]))' – dmvianna

1

如果您升级到numpy 1.7(其中datetime仍标记为实验),以下内容应该可以工作。

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

请注意,从1.9开始,此方法无效。分界线旨在将时间跨度转换为浮点数年。它不提取他们年份的日期属性。 – jdr5ca

0

有没有直接的方法来做到这一点呢,很遗憾,但也有一些间接的方法:

[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()可能在小数点后有小数部分。

+0

这不适用于python 3.5,numpy 1.11,与我对[Ncik的回答](http://stackoverflow.com/a/35281829/210945) – naught101

16

我发现以下技巧给出了2倍和4倍的速度增加与上述熊猫方法(即pd.DatetimeIndex(dates).year等)。我发现[dt.year for dt in dates.astype(object)]的速度与熊猫方法类似。另外,这些技巧可以直接应用于(2D,3D等),任意形状的ndarrays

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 
+0

的评论相同的原因。这是一个很好的解决方案。如果在numpy中有这样简单的东西,那会非常好。 – naught101

+0

感谢您给出的答案,而不是说“您不应该使用,而是使用”。 –

4

应该有这样做更简单的方法,但是,这取决于你想做什么,最好的路线可能是转换为常规Python datetime object

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.x的

+0

而且你可以使用列表操作在整个数组上执行此操作[由@acjay概述](http://stackoverflow.com/a/13654502/1304462):'[dt.year for dtime64Array.astype(object) ]' – Nick

+0

这段代码可以工作,但是如果我给它一个不同的np.datetime64(从我的DataFrame中获得一个日期),它将计算为long而不是datetime ...即使我明确使用astype(datetime.datetime),它的计算结果也会变长。 ..怪异的... –

+0

@ Mr.WorshipMe对此不确定。可能值得编写一个更详细的版本,显示双重行为的例子。然后在这里提交一个带有链接的新问题。 – Nick

0

工作中使用numpy的版本1.10.4和熊猫版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) 
0

Anon's answer的伟大工程,为我,但我只需要修改语句days

来自:

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

发送至:

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

这个答案可能应该变成对你提到的Anon的回答的评论(或编辑)。 – firegurafiku

0

另一种可能性是:

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

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

,但只适用于标量值,不会采取阵列