feat(unitproc):Add py function to expand/reduce numeric lists
[BK-2020-03.git] / unitproc / python / bktemp-subsetExpandReduce.py
1 #!/usr/bin/env python3
2
3 # Desc: Expand or reduce list of int/floats to specified length.
4
5 import numpy as np
6
7 def medianSubset(listIn: list = [], listOutLen: int = 0) -> list:
8 # Input: int: listOutLen: quantity of elements in output list
9 # list: listIn: input list consisting of integers or floats
10 # Output: list: ints/floats of specified size
11 # Ref/Attrib: PEP 3107 typing https://stackoverflow.com/a/21384492
12 # Version: 0.1.0
13 #print('DEBUG:listOutLen:' + str(listOutLen))
14 #print('DEBUG:listIn:' + str(listIn))
15
16 # Exit for invalid input
17 if not isinstance(listOutLen, int):
18 raise ValueError('ERROR:Not a valid int:' + str(listOutLen))
19 else:
20 if not listOutLen > 0:
21 raise ValueError('ERROR:Invalid value:' + str(listOutLen))
22 if not isinstance(listIn, list):
23 raise ValueError('ERROR:Not a valid list:' + str(listOutLen))
24 if not all([( (isinstance(x,int)) or (isinstance(x,float)) ) for x in listIn]):
25 raise ValueError('ERROR:Input list contains something besides integers or floating point numbers.')
26
27 # Initialize listOut
28 listOut = [None] * listOutLen
29 #print('DEBUG:listOut:' + str(listOut))
30
31 # Calc listIn length
32 listInLen = len(listIn)
33 #print('DEBUG:listInLen:' + str(listInLen))
34
35 # Calc subset length float
36 subsetLenFloat = ( (max([listInLen,listOutLen]) - 1) /min([listInLen,listOutLen]))
37 subsetIndRatio = ( (listInLen)/(listOutLen) )
38 #print('DEBUG:subsetLenFloat: %.5f' % subsetLenFloat)
39 #print('DEBUG:subsetLenFloat2: %.5f' % subsetIndRatio)
40
41 # Iterate for each element in listOut
42 for i_out in range(listOutLen):
43 #print('DEBUG:i_out:' + str(i_out))
44 ## Decide to expand or reduce listIn to produce listOut
45 if listInLen > listOutLen:
46 ### reduce listIn to listOut
47 #print('DEBUG:listOutLen:' + str(listOutLen))
48 #print('DEBUG:listInLen:' + str(listInLen))
49 if i_out == 0:
50 #### Initialize subsetIndLo in first loop
51 subsetIndLo = int(0)
52 #print('DEBUG:subsetIndLo:' + str(subsetIndLo))
53 #print('DEBUG:i_out:' + str(i_out))
54 #### Calc indices of i_out'th subset of listIn
55 subsetIndHi = (listInLen - 1) * (i_out + 1) // listOutLen
56 subsetLen = subsetIndHi - subsetIndLo + 1
57 #print('DEBUG:subsetIndLo:' + str(subsetIndLo))
58 #print('DEBUG:subsetIndHi:' + str(subsetIndHi))
59 #print('DEBUG:subsetLen:' + str(subsetLen))
60 #### Extract subset from listIn using indices inclusively
61 subset = listIn[ int(subsetIndLo) : int(subsetIndHi)+1 ]
62 #print('DEBUG:subset:' + str(subset))
63 #### Calculate median for subset
64 subsetMedian = np.median(subset)
65 #print('DEBUG:subset median:' + str(subsetMedian))
66 #### Set listOut element
67 listOut[i_out] = subsetMedian
68 #### Housekeeping
69 ##### Update subsetIndLo for next loop
70 subsetIndLo = subsetIndHi + 1
71 #print('DEBUG:Updated subsetIndLo:' + str(subsetIndLo))
72 elif listOutLen > listInLen:
73 ### Expand listIn to listOut
74 #print('DEBUG:listOutLen:' + str(listOutLen))
75 #print('DEBUG:listInLen:' + str(listInLen))
76 #### Identify index list of lists mapping listIn to ListOut
77 expandIndex = int(i_out / subsetLenFloat)
78 expandIndex = min([expandIndex,(listInLen - 1)])
79 #print('DEBUG:expandIndex:' + str(expandIndex))
80 listOut[i_out] = listIn[expandIndex]
81 #print('DEBUG:listOut[i_out]:' + str(listOut[i_out]))
82 elif listOutLen == listInLen:
83 listOut = listIn
84 #print('DEBUG:end for loop===========')
85 return listOut
86
87 example_list1 = [738,253,104,543,501,352,770,945,992,920,977,435,783,592,261,176,888]
88 example_list2 = [641,679,371]
89 example_list3 = [738,253,104,543,501,352,770,945,992,920,977,435,783,592,261,176,888,767,169,495,382,291,116,480,8,52,761,455,743,592,54,490,596,8,816,134,641,705,2,675,414,511,220,60,116,563,19,316,605,735,196,210,107,848,630,392,700,94,824,329,307,693,374,511,17,488,626,730,606,273,875,466,790,40,681,954,947,981,775,498,49,327,268,492,799,273,403,839,895,200,329,373,819,302,456,23,944,543,997,605,338,919,385,783,339,825,457,761,994,530,862,504,690,720,10,102,662,579,835,747,337,471,409,904,321,928,908,573,984,853,244,499,940,468,480,668,128,570,584,325,940,230,738,624,672,601,384,242,800,172,125,150,124,958,242,560,829,22,614,707,677,413,800,536,269,748,209,821,212,939,196,2,830,815,235,847,456,181,920,413,153,935,626,215,821,813,847,875,550,656,237,760,718,179,549,63,839,204,631,917,95,733,341,881,539,561,227,492,549,423,565,856,384,376,809,920,116,609,205,644,791,187,15,55,776,376,882,905,937,304,626,312,263,16,163,651,422,656,116,495,158,156,981,167,786,536,987,697,88,354,335,281,718,562,169,783,483,16,314,344,760,189,965,494,68,314,806,26,866,741,283,302,761,518,713,264,570,239,410,629,47,547,270,94,228,303,811,795,658,102,96,438,157,62,826,27,382,847,341,953,671,147,746,408,201,536,809,235,778,41,266,682,686,620,279,167,183,533,471,173,145,676,774,191,885,583,694,1000,484,115,159,31,704,248,852,441,901,705,829,496,784,163,88,1,503,986,929,631,839,124,55,136,907,342,863,328,417,674,881,567,876,30,812,515,606,469,725,478,100,149,881,12,221,839,138,354,712,550,698,931,914,610,704,513,477,527,388,341,373,77,673,970,612,384,613,321,411,382,273,100,55,760,246,161,268,348,22,533,851,515,807,76,396,254,554,503,322,292,821,345,147,303,225,389,356,119,530,502,407,474,824,900,561,624,292,893,597,60,393,856,675,27,257,535,5,879,809,944,904,327,209,626,440,102,528,970,839,77,0,987,422,414,337,499,266,640,194,454,414,517,221,83,4,473,84,39,831,640,557,685,45,91,410,327,734,470,928,22,837,583,570,671,773,94,317,935,365,319,965,465,723,471,77,420,683,581,604,17,373,767,722,15,742,533,497,847,8,84,842,28,526,591,466,396,807,676,564,695,967,47,886,266,638,767,58,763,775,778,25,699,895,64,616,11,369,521,856,277,726,165,281,692,736,256,545,912,954,325,620,220,407,304,191,363,884,818,138,783,559,164,516,880,791,884,246,963,522,547,356,475,302,582,687,399,862,109,524,570,867,961,780,611,491,677,977,879,803,651,41,400,634,415,750,129,89,861,265,669,833,833,333,221,102,505,353,264,31,782,595,838,365,141,475,697,46,503,71,205,164,811,46,57,278,278,12,297,33,326,106,916,352,528,616,21,129,534,485,753,410,952,758,26,152,123,578,42,33,881,145,71,662,902,782,634,256,598,265,953,135,778,407,990,643,309,448,381,620,559,208,648,830,332,59,420,456,558,439,503,182,728,486,568,986,172,652,176,380,542,92,551,335,602,854,485,543,752,860,163,120,607,207,710,298,711,32,908,228,41,481,313,581,874,443,273,204,265,567,792,326,173,29,762,398,923,18,312,144,965,764,342,884,395,624,853,709,7,424,11,836,677,210,717,950,525,782,39,770,972,993,517,495,323,772,133,941,300,809,517,574,243,664,772,721,232,304,429,864,135,667,871,371,894,485,86,42,445,426,556,588,205,533,392,900,962,112,837,961,617,302,779,793,969,199,199,591,747,321,453,861,145,451,149,887,726,414,696,421,260,92,159,56,528,879,844,408,568,603,182,492,796,656,876,566,468,237,400,629,366,868,145,150,151,561,738,241,891,813,235,400,476,224,241,169,157,969,540,901,925,723,536,421,369,24,560,882,817,677,234,16,241,464,923,849,300,144,261,916,529,586,905,268,950,673,697,664,840,725,926,603,96,845,410,321,9,996,844,952,380,272,125,140,719,402,383,499,9,48,955,429,458,965,584,381,739,984,10,282,165,486,33,353,616,304,215,293,362,148,542,815,659,874,890,502,369,499,533,144,876,169,375,951,784,320,782,763,473,38,871,790,933,522,88,702,387,705,544,575,719,757,867,470,807,628,914,719,764,536,748,766,419,42,604,678,742,321,280,147,975,918,982,440,842,723,910,893,111,560,922,837,116,858,374,262,878,354,397,638,338,853]
90 example_list4 = [641,679,371,3.141592]
91 example_list5 = [641,679,371,3.141592, 'jan']
92 #print(medianSubset(example_list,3))
93 #print(medianSubset(example_list2,17))
94 #print(medianSubset(example_list3,3))
95 #print(medianSubset(example_list3,1))
96 #print(medianSubset(example_list4,1))
97 print(medianSubset(example_list3,47))