I don't have cftime installed, so will demonstrate with regular datetime objects.
First make an array of datetime objects - the lazy way using numpy's own datetime dtype:
In [599]: arr = np.arange('2000-01-11','2000-12-31',dtype='datetime64[D]')
In [600]: arr.shape
Out[600]: (355,)
Make an object dtype array from that:
In [601]: arrO = arr.astype(object)
and a list of datetimes as well:
In [602]: alist = arr.tolist()
Timing for regular list comprehension:
In [603]: timeit [d.month for d in alist]
20.1 µs ± 62.7 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
List comprehension on a object dtype array is usually a bit slower (but faster than a list comprehension on a regular array):
In [604]: timeit [d.month for d in arrO]
30.7 µs ± 266 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
frompyfunc - here it's slower; other times I've see it 2x faster than a list comprehension:
In [605]: timeit np.frompyfunc(lambda x: x.month, 1,1)(arrO)
51 µs ± 32.4 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
vectorize is (nearly) always slower than frompyfunc (even though it uses frompyfunc for the actual iteration):
In [606]: timeit np.vectorize(lambda x: x.month, otypes=[int])(arrO)
76.7 µs ± 123 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Here are samples of the arrays and list:
In [607]: arr[:5]
Out[607]:
array(['2000-01-11', '2000-01-12', '2000-01-13', '2000-01-14',
'2000-01-15'], dtype='datetime64[D]')
In [608]: arrO[:5]
Out[608]:
array([datetime.date(2000, 1, 11), datetime.date(2000, 1, 12),
datetime.date(2000, 1, 13), datetime.date(2000, 1, 14),
datetime.date(2000, 1, 15)], dtype=object)
In [609]: alist[:5]
Out[609]:
[datetime.date(2000, 1, 11),
datetime.date(2000, 1, 12),
datetime.date(2000, 1, 13),
datetime.date(2000, 1, 14),
datetime.date(2000, 1, 15)]
frompyfunc and vectorize are best used when you want the generality of broadcasting and multidimensional arrays. For 1d arrays, a list comprehension is nearly always better.
To fairer to frompyfunc, I should return an array from the list comprehension:
In [610]: timeit np.array([d.month for d in arrO])
50.1 µs ± 36.3 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
To get the best speed with dates in numpy, use the datatime64 dtype instead of object dtype. This makes more use of compiled numpy code.
In [611]: timeit arr = np.arange('2000-01-11','2000-12-31',dtype='datetime64[D]'
...: )
3.16 µs ± 51 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [616]: arr.astype('datetime64[M]')[::60]
Out[616]:
array(['2000-01', '2000-03', '2000-05', '2000-07', '2000-09', '2000-11'],
dtype='datetime64[M]')
list = [ele] * n, but the elements all reference the same memory space - modifying any of them will affect the others. Loop/list comprehension avoids this.num2datefunction of the the cftime package.cftimeis written incython(Python compiled toc(as much as possible)). So make sure you use its own functionality as much as possible.