Python 从numpy数组到datetimes数组的时间值
如果有一个大数组,其中列[0]对应于天,列[1]=月,列[2]=年,列[3]=小时(后者是一个浮点数,还包含分数形式的分钟和秒信息),那么将这些列转换为日期时间数组的最有效方法是什么 下面的更新:我修改了dt.datetime函数,使其能够处理数组输入以及小数年、月等。我还没有完全测试过这个,可能有更优雅的方法来做,但现在开始Python 从numpy数组到datetimes数组的时间值,python,numpy,Python,Numpy,如果有一个大数组,其中列[0]对应于天,列[1]=月,列[2]=年,列[3]=小时(后者是一个浮点数,还包含分数形式的分钟和秒信息),那么将这些列转换为日期时间数组的最有效方法是什么 下面的更新:我修改了dt.datetime函数,使其能够处理数组输入以及小数年、月等。我还没有完全测试过这个,可能有更优雅的方法来做,但现在开始 from __future__import division def getrem(input): "this function yields the valu
from __future__import division
def getrem(input):
"this function yields the value behind the decimal point"
import numpy as np
output=abs(input-np.fix(input))
return output
def datenum(Yr,Mo=1,Da=1,Hr=0,Mi=0,Se=0,Ms=0):
"this function works as regular datetime.datetime, but allows for float input"
import numpy as np
import datetime as dt
import calendar
#correct faulty zero input
if Mo<1:
Mo+=1
if Da<1:
Da+=1
#distribute the year fraction over days
if getrem(Yr)>0:
if calendar.isleap(np.floor(Yr)):
fac=366
else:
fac=365
Da=Da+getrem(Yr)*fac
Yr=int(Yr)
#if months exceeds 12, pump to years
while int(Mo)>12:
Yr=Yr+1
Mo=Mo-12
#distribute fractional months to days
if getrem(Mo)>0:
Da=Da+getrem(Mo)*calendar.monthrange(Yr,int(Mo))[1]
Mo=int(Mo)
#datetime input for 28 days always works excess is pumped to timedelta
if Da>28:
extraDa=Da-28
Da=28
else:
extraDa=0
# sometimes input is such that you get 0 day or month values, this fixes this anomaly
if int(Da)==0:
Da+=1
if int(Mo)==0:
Mo+=1
#datetime calculation
mytime=dt.datetime(int(Yr),int(Mo),int(Da))+dt.timedelta(days=extraDa+getrem(Da),hours=Hr,minutes=Mi,seconds=Se,microseconds=Ms)
return mytime
def araydatenum(*args):
mydatetimes=[datenum(*[a.squeeze()[x] for a in args]) for x in range(len(args[0].squeeze()))]
return mydatetimes
来自未来进口部的
def getrem(输入):
“此函数生成小数点后的值”
将numpy作为np导入
输出=abs(输入np.fix(输入))
返回输出
def datenum(年,月=1,日=1,时=0,月=0,月=0,月=0,月=0):
此函数与常规datetime.datetime一样工作,但允许浮点输入
将numpy作为np导入
将日期时间导入为dt
导入日历
#纠正错误的零输入
如果Mo12:
年=年+1
Mo=Mo-12
#将零碎的月份分配到天
如果getrem(Mo)>0:
Da=Da+getrem(Mo)*日历。蒙特兰奇(年,国际(Mo))[1]
Mo=int(Mo)
#28天的datetime输入始终有效,超出部分被泵入timedelta
如果Da>28:
extraDa=Da-28
Da=28
其他:
extraDa=0
#有时输入值为0天或0月,这将修复此异常
如果int(Da)==0:
Da+=1
如果int(Mo)==0:
Mo+=1
#日期时间计算
mytime=dt.datetime(int(Yr)、int(Mo)、int(Da))+dt.timedelta(days=extraDa+getrem(Da),小时=Hr,分钟=Mi,秒=Se,微秒=Ms)
返回我的时间
def araydatenum(*参数):
mydatetimes=[datenum(*[a.Squence()[x]表示参数中的a])表示范围中的x(len(参数[0].Squence())]
返回mydatetimes
无法与最高效的人交谈,但可以像这样轻松完成:
import datetime as dt
mydatetimes = [dt.datetime(x[2], x[1], x[0]) + dt.timedelta(hours=x[3]) for x in myarray]
这将创建一个常规python列表,而不是numpy数组。只需在右侧添加
numpy.array(…)
,使其成为一个带有dtype=object
按日期时间排列的数组。您是指Pythondatetime.datetime
对象(您需要一个dtype='object'数组),或者你的意思是在NumPy 1.7中引入的?这两种格式都会让你有分数年和分数月吗?听起来很痛苦。:-)顺便说一句,timedelta将处理额外的小时、分钟和秒数,至少可以为您节省一部分剩余时间。小数年是一种常见现象,天数有时是小时。几个月是相当罕见的。关于timedelta,你是对的,我可能会进一步调整它。一个变体是np。沿_轴(foo,1,myarray)
,其中foo
是围绕dt.datetime…
的简单函数包装器。但是它实际上比你的np.numpy([foo(x)表示myarray中的x])
慢。对于这样的自定义操作,简单的Python通常是最好的起点。这是可行的(请参见上面的编辑更新),但我仍然想知道是否不能避免For循环(或沿_轴应用_)。