从Python中的numpy数组输入获取“Day of Year”数组

时间:2017-04-13 12:00:02

标签: python arrays numpy

我有numpy数组中的数据,包括Year,Month和Day作为列, 我想计算朱利安日或“年日”(DOY)也应该是一个numpy数组。

计算DOY的公式是:

import datetime
y = 2017
m = 4
d = 13
DOY = int(dt.datetime(y, m, d).strftime('%j')

它将打印103

假设我们将y_arm_ard_ar作为年,月和日的数组,

我试过了:

julians = int(dt.datetime(y_ar, m_ar, d_ar).strftime('%j'))

它给了我TypeError: only length-1 arrays can be converted to Python scalars  我尝试了其他成功的

julians = np.array(map(lambda (y, m, d): int(dt.datetime(y, m, d).strftime('%j')), zip(y_ar, m_ar, d_ar)))

虽然它给了我想要的东西,但是我觉得按元素逐个获取然后输出一个列表然后将它转换回没有numpy数组会有点费时间!

任何人都可以帮我确定错误发生的原因,并且有更好,更快的方法吗?

示例数组有助于测试解决方案:

y_ar = np.array([1990, 2000, 2015, 2017])
m_ar = np.array([5, 8, 1, 12])
d_ar = np.array([13, 7, 30, 29])

1 个答案:

答案 0 :(得分:2)

datetime与numpy数组结合使用通常会很慢,因为它会创建带有dtype=object的数组。但是,从版本1.7.0开始,numpy有一个内置datetime64 type

使用起来有点奇怪,但这似乎有效:

原始解决方案(列表理解而不是地图)

import datetime as dt

y_ar = np.array([1990, 2000, 2015, 2017])
m_ar = np.array([5, 8, 1, 12])
d_ar = np.array([13, 7, 30, 29])

julians_ref = np.array([int(dt.datetime(y, m, d).strftime('%j')) for y, m, d in zip(y_ar, m_ar, d_ar)])

本地numpy解决方案

y_ar = (y_ar - 1970).astype('M8[Y]')
m_ar = (m_ar - 1).astype('m8[M]')
d_ar = (d_ar - 1).astype('m8[D]')

date_ar = y_ar + m_ar + d_ar  # full date
julians = date_ar - y_ar + 1  # days since first day of the year

print(julians_ref)  # [133 220  30 363]
print(julians)  # [133 220  30 363]
julians = int(dt.datetime(y_ar, m_ar, d_ar).strftime('%j'))
     

它给出了我的TypeError:只有length-1数组可以转换为我试过的Python标量

这是因为datetime.datetime不知道numpy数组。期望年,月和日的标量(=单个)值。当解释器尝试将数组转换为标量时,这会失败,除非数组等效于标量(它只有一个元素)。