區間映射到區間 in Python


問題

需要情形下,需要將一個區間映射到另一個區間。如將0-1映射到10-32之間,應該如何設計算法?

場景1

比如某大學教師在學校規定的掛科機率下進行期末考試,如果學生都考得很差,那么他就需要根據適當的形式去調整學生的成績。

比如,學生的成績普遍較差,分布在20分到65分之間,那么需要映射到55-100之間,將及格率調高。

場景2

某學生是某國交換生,但是在某國的成績是5-18,但國內的成績是0-100,需要將國外考試的成績反映到國內的成績單上。那么也就是將 5-18 映射到 0-100,將 [5-18] -5 = [0, 13],假設小明的成績是 12, 那么國內的成績就是 12*(100/13),原理也就是先歸零,然后再同比例縮放

原理

假設需要縮放的數據是X,需要映射到的范圍是 [a, b], 那么可以用以下公式來進行。

\[Y=a+\frac{b-a}{X_{max}-X_{min}}.(X-X_{min}) \]

代碼

def map_rate(X:list, to_min:float, to_max:float)->list:
    """區間映射
    
    Attribute:
    
    - X: 需要映射的列表
    - to_min: 要映射到的最小值
    - to_max: 要映射到的最大值
    """
    x_min=min(X)
    x_max=max(X)
    return list([round(to_min+((to_max - to_min) / (x_max - x_min)) * i - x_min,1) for i in X])

這個代碼比較簡單,參數就是上述所提到的三個參數:需要映射的列表, 要映射到的 start 和 end, 最后的結果 round(x, 2)了一下,保留一位小數,否則得到的結果太過精確。

實驗

如隨機生成的學生成績=,再將他們映射到某一范圍。

X=[67, 45, 81, 95, 23, 77, 65, 32, 55, 22]
map_rate(X, 60, 100)

結果是

[74.7, 62.7, 82.4, 90.1, 50.6, 80.2, 73.6, 55.5, 68.1, 50.1]

分布問題

有點好奇這樣是否會影響其分布,推測不會,因為是同比例縮放。於是使用了葡萄牙某中學學生在校成績數據集,網址是:https://www.mldata.io/dataset-details/school_grades/#customize_download

用上述方法,對數學的成績分布進行了驗證。

data1=pd.read_csv("./學生成績.csv",encoding='utf8')
with open("./result.csv",'w',encoding='utf8') as f:
    result_list="\n".join([str(i) for i in map_rate(list(data1['G3']),60,100)])
    f.writelines(result_list)

結果如圖所示。

可以看到,基本沒有變化,但是會有部分變化,這是因為分布的分箱不同導致的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM