datetime.discretize
datetime: bin = discretize (T, edges)
datetime: bin = discretize (T, N)
datetime: bin = discretize (T, dur)
datetime: bin = discretize (T, unit)
datetime: Y = discretize (…, values)
datetime: C = discretize (…, ’categorical’)
datetime: C = discretize (…, ’categorical’, names)
datetime: [bin, E] = discretize (…)
Group datetimes into bins.
bin = discretize (T, edges) returns, for each
element of T, the index of the bin of the datetime vector
edges that contains it. Bins are half open,
[E(j), E(j+1)), except the last which is closed at
both ends. Elements outside the edges, and NaT elements, give
NaN.
bin = discretize (T, N) uses N bins
spanning the data, placed on whole calendar or clock units wherever that
can be done without leaving a bin unused.
bin = discretize (T, dur) uses bins one
dur wide, where dur is a scalar duration or
calendarDuration, aligned to whole multiples of that width.
bin = discretize (T, unit) uses bins one named
unit wide, unit being one of 'second', 'minute',
'hour', 'day', 'week', 'month',
'quarter', 'year', 'decade' or
'century'. These land on real calendar boundaries: a
'week' bin starts on a Sunday, a 'quarter' on 1 January,
1 April, 1 July or 1 October, and a 'decade' on a year that is a
multiple of ten.
Y = discretize (…, values) returns
values(bin) instead of the bin index, and
C = discretize (…, 'categorical') returns a
categorical array whose categories are named after the bins.
[bin, E] = discretize (…) also returns the bin
edges as a datetime array carrying this array’s Format
and TimeZone.
Note that whether a bin follows the calendar depends on how its width
is given, not on how long that width is. A named unit ('day'
and coarser) or a calendarDuration width begins at
local midnight, so in a time zone that observes daylight
saving the bin holding a transition is 23 or 25 hours long while its
neighbours are 24. A duration width is a fixed span of elapsed
time whatever its length: days (1) bins are each exactly 24
hours, and their edges therefore read an hour later on the far side of
a transition. The two agree for an unzoned array, and for a zoned one
that spans no transition.
A named unit opens one bin past the data when the largest element sits
on a unit boundary of the wall clock. Sub-day bins step in elapsed
time, so in a zone whose shift is not a whole number of those units –
Australia/Lord_Howe moves its clock half an hour, against an
'hour' bin – the grid leaves the wall clock past a transition
and an element may then land mid-unit. Such an element gets a bin of
its own here. This is deliberately unlike MATLAB, which closes
its last edge short of it and leaves it out of every bin.
Deviation from MATLAB: bin placement where a zone’s clock shifts
by a fraction of the bin unit. A bin grid is anchored on the wall clock
and stepped in elapsed time, so a zone that moves its clock by less than
one bin unit – Australia/Lord_Howe moves it half an hour – puts
the grid out of step with the clock from the transition onward. Where
the shift is exactly half a unit the placement matches MATLAB,
having been measured against it. For any other fraction, which today
arises only from the historical offset changes of the early twentieth
century (Asia/Singapore moved by twenty minutes in 1933), the
placement is our own: the grid is centred on the data with no
correction for the transition, exactly as in a zone that has none.
MATLAB places those bins differently, by a rule we have not been able to
derive from its output; both cover the data, and neither is more correct
than the other. Only a requested bin count is affected – and
'auto', 'scott', 'fd', 'sturges' and
'sqrt', which resolve to one. An explicit 'BinWidth' or
a named unit is placed identically to MATLAB in every zone.
A bin width below a second carries a little noise in its edges. An instant is counted in seconds from 1970 and so runs to about 1.7e9, where a double resolves to some 2e-7 of a second; a width of, say, 0.4 s therefore lands its edges within a few hundred nanoseconds of the exact grid rather than on it. The opening edge is exact, the drift is in the step, and it is a limit of the representation rather than of the placement.
When T is empty the edges are anchored on the epoch,
1970-01-01. This is deliberately unlike MATLAB, which
answers an empty datetime with edges taken from the current
clock, so that the same call returns a different result every time it is
run.
Source Code: datetime