I have data in numpy array that include Year, Month, and Day as columns, I want to calculate the Julian day or the 'Day of Year' (DOY) that should be a numpy array as well.
The formula to calculate DOY is:
import datetime
y = 2017
m = 4
d = 13
DOY = int(dt.datetime(y, m, d).strftime('%j')
it will print 103
Assuming we have y_ar, m_ar, and d_ar as the arrays of years, months, and days,
I tried this:
julians = int(dt.datetime(y_ar, m_ar, d_ar).strftime('%j'))
it gives my TypeError: only length-1 arrays can be converted to Python scalars
I tried something else which succeeded:
julians = np.array(map(lambda (y, m, d): int(dt.datetime(y, m, d).strftime('%j')), zip(y_ar, m_ar, d_ar)))
Although it gives me what I want, but I feel that it is a bit time consuming to take element by element, then to output a list, then to convert it back no numpy array!
Can anyone help me determine why the error occurs, and wheather there is a better, faster way to do so?
Sample arrays to help to test the solution:
y_ar = np.array([1990, 2000, 2015, 2017])
m_ar = np.array([5, 8, 1, 12])
d_ar = np.array([13, 7, 30, 29])
Using datetime in combination with numpy arrays will be slow in general because it will create arrays with dtype=object. However, starting with version 1.7.0 numpy has a builtin datetime64 type.
It is a bit strange to use, but this seems to work:
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)])
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'))it gives my TypeError: only length-1 arrays can be converted to Python scalars I tried
This is because datetime.datetime is not aware of numpy arrays. is expects a scalar (=a single) value for year, month, and day. When the interpreter tries to convert an array into a scalar this fails, unless the array is equivalent to a scalar (it has only one element).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With