Here's the problem:
I have a (large) set of dates spanning 200 years between 2100 and 2300 AD like:
raw = [
'2100-09-01',
'2200-03-07',
'2295-07-27'
]
(etc. about 1M dates) I need to transform the dates to a smaller (and earlier, and also not a multiple of ten) range between 1988 and 2002 like:
transformed = [
'1988-09-01',
'1998-03-08',
'2001-08-01'
]
...such that the original distribution of values with respect to the min/mean/max of the original range is preserved and the dates are valid (i.e. not Feb 29 on a non-leap year).
Try using toordinal(). The ordinal of January 1st, 1 AD is 1.
ordinals = [d.toordinal() for d in raw]
Now you have a list of numbers, which is easy to scale:
def scale_num(raw, target_max, target_min, source_max, source_min):
scaled = (((raw - source_min)/(source_max - source_min))*(target_max - target_min))+target_min
return scaled
target_min = datetime.datetime(1988,1,1).toordinal()
target_max = datetime.datetime(2001,12,31).toordinal()
source_max = max(ordinals)
source_min = min(ordinals)
scaled = [round(scale_num(d, target_max, target_min, source_max, source_min)) for d in ordinals]
In order to transform the ordinal into a date, use date.fromordinal():
date = date.fromordinal(1).isoformat()
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