This is an old enough question that shooting for the extra points is hopefully not going to step on anyone's toes. So let me be the broadcast guy, i.e. this is a loop-free version.
It is perhaps better to first read either the numpy documentation on broadcasting, or a related answer of mine.
We start with solving the one-column case.
In this case the ...
Your regular Python implementation generally looks reasonable, and unless numpy
offers a performance boost that you really need, I would not recommend it for
this use case: the brevity/clarity tradeoff seems bad.
My biggest suggestion is to consider clearer names. A function with signature
of take_upto_n(A, n) makes me think the function takes an iterable ...
Minor style edits
Like you said, the code seems to be perfectly fine and I don't see a very obvious way to make it faster or more efficient, as the consecutive computations you are making in your for loop don't seem to be easy to relate to one another.
Of course this is just my input after thinking for some time, other people may have clever suggestions I ...
As you will be able to see from your provided sample input, your code does not produce the intended result. Here is a minimal example:
dates = np.arange(np.datetime64('2018-02-01'), np.datetime64('2018-02-05'), 2)
stride = (dates - dates)
result = np.arange(np.datetime64(dates), np.datetime64(dates[-1] + stride))
print(dates) # > ['2018-02-01' ...