Python實(shí)現(xiàn)TOPSIS分析法(優(yōu)劣解距離法)

(1)穗椅、題目

在這里插入圖片描述

題目:評(píng)價(jià)下表中20條河流的水質(zhì)情況蔓倍。
注:含氧量越高越好(極大型指標(biāo)),PH值越接近7越好(中間型指標(biāo))敞咧,細(xì)菌總數(shù)越少越好(極小型指標(biāo))棘捣,植物性營養(yǎng)物量介于10~20之間最佳,超過20或低于10均不好(范圍型指標(biāo))休建。

(2)乍恐、讀取Excel表中的數(shù)據(jù)

def read(file):
    wb = xlrd.open_workbook(filename=file)#打開文件
    sheet = wb.sheet_by_index(0)#通過索引獲取表格
    rows = sheet.nrows # 獲取行數(shù)
    all_content = []        #存放讀取的數(shù)據(jù)
    for j in range(1, 5):       #取第1~第4列對(duì)的數(shù)據(jù)
        temp = []
        for i in range(1,rows) :
            cell = sheet.cell_value(i, j)   #獲取數(shù)據(jù) 
            temp.append(cell)           
        all_content.append(temp)    #按列添加到結(jié)果集中
        temp = []
    return np.array(all_content)

(3)、將不同的指標(biāo)轉(zhuǎn)換為極大型指標(biāo)

#極小型指標(biāo) -> 極大型指標(biāo)
def dataDirection_1(datas):         
        return np.max(datas)-datas     #套公式

#中間型指標(biāo) -> 極大型指標(biāo)
def dataDirection_2(datas, x_best):
    temp_datas = datas - x_best
    M = np.max(abs(temp_datas))
    answer_datas = 1 - abs(datas - x_best) / M     #套公式
    return answer_datas
    
#區(qū)間型指標(biāo) -> 極大型指標(biāo)
def dataDirection_3(datas, x_min, x_max):
    M = max(x_min - np.min(datas), np.max(datas) - x_max)
    answer_list = []
    for i in datas:
        if(i < x_min):
            answer_list.append(1 - (x_min-i) /M)      #套公式
        elif( x_min <= i <= x_max):
            answer_list.append(1)
        else:
            answer_list.append(1 - (i - x_max)/M)
    return np.array(answer_list)   
在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

(4)测砂、正向化矩陣標(biāo)準(zhǔn)化

def temp2(datas):
    K = np.power(np.sum(pow(datas,2),axis =1),0.5)
    for i in range(0,K.size):
        for j in range(0,datas[i].size):
            datas[i,j] = datas[i,j] / K[i]      #套用矩陣標(biāo)準(zhǔn)化的公式
    return datas 
在這里插入圖片描述

(5)茵烈、計(jì)算得分并歸一化

def temp3(answer2):
    list_max = np.array([np.max(answer2[0,:]),np.max(answer2[1,:]),np.max(answer2[2,:]),np.max(answer2[3,:])])  #獲取每一列的最大值
    list_min = np.array([np.min(answer2[0,:]),np.min(answer2[1,:]),np.min(answer2[2,:]),np.min(answer2[3,:])])  #獲取每一列的最小值
    max_list = []       #存放第i個(gè)評(píng)價(jià)對(duì)象與最大值的距離
    min_list = []       #存放第i個(gè)評(píng)價(jià)對(duì)象與最小值的距離
    answer_list=[]      #存放評(píng)價(jià)對(duì)象的未歸一化得分
    for k in range(0,np.size(answer2,axis = 1)):        #遍歷每一列數(shù)據(jù)
        max_sum = 0
        min_sum = 0
        for q in range(0,4):                                #有四個(gè)指標(biāo)
            max_sum += np.power(answer2[q,k]-list_max[q],2)     #按每一列計(jì)算Di+
            min_sum += np.power(answer2[q,k]-list_min[q],2)     #按每一列計(jì)算Di-
        max_list.append(pow(max_sum,0.5))
        min_list.append(pow(min_sum,0.5))
        answer_list.append(min_list[k]/ (min_list[k] + max_list[k]))    #套用計(jì)算得分的公式 Si = (Di-) / ((Di+) +(Di-))
        max_sum = 0
        min_sum = 0
    answer = np.array(answer_list)      #得分歸一化
    return (answer / np.sum(answer))
在這里插入圖片描述

(6)、主函數(shù)

def main():
    file = 'C:\\Users\\lenovo\Desktop\\數(shù)學(xué)建模\\TOPSIS法\\第2講.TOPSIS法(優(yōu)劣解距離法)7.17\\代碼和例題數(shù)據(jù)\\20條河流的水質(zhì)情況數(shù)據(jù).xlsx'
    answer1 = read(file)        #讀取文件
    answer2 = []
    for i in range(0, 4):       #按照不同的列砌些,根據(jù)不同的指標(biāo)轉(zhuǎn)換為極大型指標(biāo)瞧毙,因?yàn)橹挥兴牧?        answer = None
        if(i == 0):             #本來就是極大型指標(biāo),不用轉(zhuǎn)換
            answer = answer1[0]             
        elif(i == 1):                   #中間型指標(biāo)
            answer = dataDirection_2(answer1[1],7)
        elif(i==2):                     #極小型指標(biāo)
            answer = dataDirection_1(answer1[2])
        else:                           #范圍型指標(biāo)
            answer = dataDirection_3(answer1[3],10,20)
        answer2.append(answer)
    answer2 = np.array(answer2)         #將list轉(zhuǎn)換為numpy數(shù)組
    answer3 = temp2(answer2)            #數(shù)組正向化
    answer4 = temp3(answer3)            #標(biāo)準(zhǔn)化處理去鋼
    data = pd.DataFrame(answer4)        #計(jì)算得分
    
    #將得分輸出到excel表格中
    writer = pd.ExcelWriter('C:\\Users\\lenovo\Desktop\\數(shù)學(xué)建模\\TOPSIS法\\第2講.TOPSIS法(優(yōu)劣解距離法)7.17\\代碼和例題數(shù)據(jù)\\A.xlsx')       # 寫入Excel文件
    data.to_excel(writer, 'page_1', float_format='%.5f')        # ‘page_1’是寫入excel的sheet名
    writer.save()
    writer.close()

(7)、完整代碼部分

# -*- coding: utf-8 -*-
"""
Created on Sat Jul 27 21:36:55 2019

@author: lenovo
"""
import numpy as np
import xlrd
import pandas as pd

#從excel文件中讀取數(shù)據(jù)
def read(file):
    wb = xlrd.open_workbook(filename=file)#打開文件
    sheet = wb.sheet_by_index(0)#通過索引獲取表格
    rows = sheet.nrows # 獲取行數(shù)
    all_content = []        #存放讀取的數(shù)據(jù)
    for j in range(1, 5):       #取第1~第4列對(duì)的數(shù)據(jù)
        temp = []
        for i in range(1,rows) :
            cell = sheet.cell_value(i, j)   #獲取數(shù)據(jù) 
            temp.append(cell)           
        all_content.append(temp)    #按列添加到結(jié)果集中
        temp = []
    return np.array(all_content)

#極小型指標(biāo) -> 極大型指標(biāo)
def dataDirection_1(datas):         
        return np.max(datas)-datas     #套公式

#中間型指標(biāo) -> 極大型指標(biāo)
def dataDirection_2(datas, x_best):
    temp_datas = datas - x_best
    M = np.max(abs(temp_datas))
    answer_datas = 1 - abs(datas - x_best) / M     #套公式
    return answer_datas
    
#區(qū)間型指標(biāo) -> 極大型指標(biāo)
def dataDirection_3(datas, x_min, x_max):
    M = max(x_min - np.min(datas), np.max(datas) - x_max)
    answer_list = []
    for i in datas:
        if(i < x_min):
            answer_list.append(1 - (x_min-i) /M)      #套公式
        elif( x_min <= i <= x_max):
            answer_list.append(1)
        else:
            answer_list.append(1 - (i - x_max)/M)
    return np.array(answer_list)   
 
#正向化矩陣標(biāo)準(zhǔn)化
def temp2(datas):
    K = np.power(np.sum(pow(datas,2),axis =1),0.5)
    for i in range(0,K.size):
        for j in range(0,datas[i].size):
            datas[i,j] = datas[i,j] / K[i]      #套用矩陣標(biāo)準(zhǔn)化的公式
    return datas

#計(jì)算得分并歸一化
def temp3(answer2):
    list_max = np.array([np.max(answer2[0,:]),np.max(answer2[1,:]),np.max(answer2[2,:]),np.max(answer2[3,:])])  #獲取每一列的最大值
    list_min = np.array([np.min(answer2[0,:]),np.min(answer2[1,:]),np.min(answer2[2,:]),np.min(answer2[3,:])])  #獲取每一列的最小值
    max_list = []       #存放第i個(gè)評(píng)價(jià)對(duì)象與最大值的距離
    min_list = []       #存放第i個(gè)評(píng)價(jià)對(duì)象與最小值的距離
    answer_list=[]      #存放評(píng)價(jià)對(duì)象的未歸一化得分
    for k in range(0,np.size(answer2,axis = 1)):        #遍歷每一列數(shù)據(jù)
        max_sum = 0
        min_sum = 0
        for q in range(0,4):                                #有四個(gè)指標(biāo)
            max_sum += np.power(answer2[q,k]-list_max[q],2)     #按每一列計(jì)算Di+
            min_sum += np.power(answer2[q,k]-list_min[q],2)     #按每一列計(jì)算Di-
        max_list.append(pow(max_sum,0.5))
        min_list.append(pow(min_sum,0.5))
        answer_list.append(min_list[k]/ (min_list[k] + max_list[k]))    #套用計(jì)算得分的公式 Si = (Di-) / ((Di+) +(Di-))
        max_sum = 0
        min_sum = 0
    answer = np.array(answer_list)      #得分歸一化
    return (answer / np.sum(answer))


def main():
    file = 'C:\\Users\\lenovo\Desktop\\數(shù)學(xué)建模\\TOPSIS法\\第2講.TOPSIS法(優(yōu)劣解距離法)7.17\\代碼和例題數(shù)據(jù)\\20條河流的水質(zhì)情況數(shù)據(jù).xlsx'
    answer1 = read(file)        #讀取文件
    answer2 = []
    for i in range(0, 4):       #按照不同的列宙彪,根據(jù)不同的指標(biāo)轉(zhuǎn)換為極大型指標(biāo)矩动,因?yàn)橹挥兴牧?        answer = None
        if(i == 0):             #本來就是極大型指標(biāo),不用轉(zhuǎn)換
            answer = answer1[0]             
        elif(i == 1):                   #中間型指標(biāo)
            answer = dataDirection_2(answer1[1],7)
        elif(i==2):                     #極小型指標(biāo)
            answer = dataDirection_1(answer1[2])
        else:                           #范圍型指標(biāo)
            answer = dataDirection_3(answer1[3],10,20)
        answer2.append(answer)
    answer2 = np.array(answer2)         #將list轉(zhuǎn)換為numpy數(shù)組
    answer3 = temp2(answer2)            #數(shù)組正向化
    answer4 = temp3(answer3)            #標(biāo)準(zhǔn)化處理去鋼
    data = pd.DataFrame(answer4)        #計(jì)算得分
    
    #將得分輸出到excel表格中
    writer = pd.ExcelWriter('C:\\Users\\lenovo\Desktop\\數(shù)學(xué)建模\\TOPSIS法\\第2講.TOPSIS法(優(yōu)劣解距離法)7.17\\代碼和例題數(shù)據(jù)\\A.xlsx')       # 寫入Excel文件
    data.to_excel(writer, 'page_1', float_format='%.5f')        # ‘page_1’是寫入excel的sheet名
    writer.save()
    writer.close()

main()

(8)释漆、計(jì)算結(jié)果

在這里插入圖片描述

計(jì)算出結(jié)果后可通過excel表對(duì)得分進(jìn)行手動(dòng)排序

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末悲没,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子男图,更是在濱河造成了極大的恐慌示姿,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逊笆,死亡現(xiàn)場離奇詭異栈戳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)难裆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門子檀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人乃戈,你說我怎么就攤上這事褂痰。” “怎么了症虑?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵缩歪,是天一觀的道長。 經(jīng)常有香客問我谍憔,道長匪蝙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任习贫,我火速辦了婚禮逛球,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沈条。我一直安慰自己,他們只是感情好诅炉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布蜡歹。 她就那樣靜靜地躺著,像睡著了一般涕烧。 火紅的嫁衣襯著肌膚如雪月而。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天议纯,我揣著相機(jī)與錄音父款,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛憨攒,可吹牛的內(nèi)容都是我干的世杀。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼肝集,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼瞻坝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起杏瞻,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤所刀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后捞挥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浮创,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年砌函,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了斩披。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胸嘴,死狀恐怖雏掠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情劣像,我是刑警寧澤乡话,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站耳奕,受9級(jí)特大地震影響绑青,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜屋群,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一闸婴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芍躏,春花似錦邪乍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至否纬,卻和暖如春吕晌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背临燃。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國打工睛驳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烙心,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓乏沸,卻偏偏與公主長得像淫茵,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子屎蜓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1. 簡述相關(guān)分析和回歸分析的區(qū)別和聯(lián)系痘昌。 回歸分析和相關(guān)分析都是研究兩個(gè)或兩個(gè)以上變量之間關(guān)系的方法。 廣義上說...
    安也也閱讀 8,670評(píng)論 0 3
  • 『上帝親吻我的左手』 我從天堂路過 上帝親吻我的左手 我變成了滿樹的花朵 花朵中的一瓣 在某個(gè)春天的尾巴 悄悄地 ...
    花城小鎮(zhèn)花藝閱讀 377評(píng)論 1 1
  • 世上所有的事的結(jié)果炬转,都是最終離開了曾經(jīng)想方設(shè)法不想要離開的人辆苔,離開了曾經(jīng)想方設(shè)法想要離開的地方……
    藍(lán)丼閱讀 300評(píng)論 1 4
  • 真正的速度是看不見的驻啤,就像風(fēng)起云涌,日落月升荐吵,就像你不知道樹葉什么時(shí)候變黃骑冗,嬰兒什么時(shí)候長出第一顆牙齒,就像你不知...
    流波舞閱讀 214評(píng)論 0 0
  • 2019.4.13 陰先煎,周六1.隨意瀏覽一些文章贼涩,無意中看到整理師,營養(yǎng)師薯蝎,心理咨詢師這些遥倦,可以充實(shí)以后的生活~2...
    關(guān)關(guān)_hcyr閱讀 90評(píng)論 0 2