Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scale a date range using Python

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).

like image 363
bloodrootfc Avatar asked Sep 19 '26 01:09

bloodrootfc


1 Answers

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()
like image 168
Alec Avatar answered Sep 20 '26 14:09

Alec