Topsis优劣解距离法python代码实现

 positive_transform.py

#positive_transform.py
import numpy as np
import pandas as pd

#positive_transform模块
#作用:将指标正向化,支持的指标类型:极小型、中间型、区间型
#x:numpy.ndarray pandas.Series

#极小型指标转极大型
def min2max(x):
    return (max(x)-x).values

#中间型指标转极大型
def mid2max(x,mid):  #mid:中间最优值
    M=max(abs(x-mid))
    return (1-(abs(x-mid)/M)).values

#区间型指标转极大型  #[a,b]最优区间
def interval2max(x,a,b):
    M=max(abs(min(x)-a),abs(max(x)-b))
    x_pos=[]
    for i in x:
        if i<a:
            i=1-abs(a-i)/M
        elif i>b:
            i=1-abs(i-b)/M
        else:
            i=1
        x_pos.append(i)
    return x_pos

#正向化
def positive(data):
    indexes=data.columns
    data_pos = data.copy()
    ques1 = int(input('是否有极小化指标:1是,0否'))
    if ques1:
        min_cols = input('输入极小化指标所在列索引{用,分隔}:')
        min_cols = min_cols.split(',')
        for col in min_cols:
            col = int(col.strip())
            data_pos[indexes[col]] = min2max(data_pos[indexes[col]])

    ques2 = int(input('是否有中间型指标:1是,0否'))
    if ques2:
        mid_cols = input('输入中间型指标所在列索引{用,分隔}:')
        mid_cols = mid_cols.split(',')
        for col in mid_cols:
            col = int(col.strip())
            mid = int(input(f'对于{indexes[col]}列,输入中间值:'))
            data_pos[indexes[col]] = mid2max(data_pos[indexes[col]], mid)

    ques3 = int(input('是否有区间化指标:1是,0否'))
    if ques3:
        interval_cols = input('输入区间型指标所在列索引{用,分隔}:')
        interval_cols = interval_cols.split(',')
        for col in interval_cols:
            col = int(col.strip())
            a = int(input(f'对于{indexes[col]}列,输入区间最小值:'))
            b = int(input(f'对于{indexes[col]}列,输入区间最大值:'))
            data_pos[indexes[col]] = interval2max(data_pos[indexes[col]], a, b)

    return data_pos

 Topsis.py

import numpy as np
import pandas as pd
import positive_transform as pt
import 层次分析法.JudgeMatrix as JM
import matplotlib.pyplot as plt


plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


#1、导入数据,示例water_condition.xlsx
data=pd.read_excel('water_condition.xlsx',sheet_name='Sheet1')
data=data.set_index('河流')
indexes=data.columns
print(data)

#2、正向化
print('正在进行正向化:')
data_pos=pt.positive(data)
print(f'正向化结果:\n{data_pos}')

#3、标准化
data_pos_standard=data_pos/np.linalg.norm(data_pos,axis=0)
print(f'标准化结果:\n{data_pos_standard}')

#4、计算最大值向量与最小值向量
min_V=data_pos_standard.min(axis=0)
max_V=data_pos_standard.max(axis=0)

flag=int(input('是否给各指标确定权重[1-是,0-否]:'))
#计算指标权重向量(默认等权)
Weights=[1/len(indexes)]*len(indexes)

if flag:
    opt1=int(input('是否直接输入权重向量[1-是,0-否]:'))
    if opt1:
        Weight_str=input('直接输入权重向量[数字用,分隔]:')
        Weight_list=Weight_str.split(',')
        Weights=[float(i.strip()) for i in Weight_list]
    else:
        opt2 = int(input('是否直接判断矩阵确定权重向量[1-是,0-否]:'))
        if opt2:
            Weights=JM.Judge_Matrix_Weight()
print(f'权重向量为{Weights}')

#5、Topsis算法计算各向量与最值向量距离
D_P=np.sqrt(((data_pos_standard.subtract(max_V,axis=1))**2).multiply(Weights,axis=1).sum(axis=1))#计算每一个向量与最大值向量距离
D_N=np.sqrt(((data_pos_standard.subtract(min_V,axis=1))**2).multiply(Weights,axis=1).sum(axis=1))#计算每一个向量与最小值向量距离

#6、计算各评价对象得分并归一化
S=D_N/(D_P+D_N)
S=S/S.sum()
result=pd.Series(data=S,index=data.index)
print('最终得分为:')
print(result)
result_sorted=result.sort_values(ascending=False)
print('根据得分降序排列为:')
print(result_sorted)

#7、绘制条形图
plt.barh(result_sorted.index,result_sorted.values)
plt.xlabel('评分')
plt.ylabel('河流')
plt.title('河流评分排序')
plt.show()

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值