python秩和比综合评价代码记录

import pandas as pd
import numpy as np
from collections import Counter
import statsmodels.api as sm
import scipy.stats

def rsr(data, weight=None, threshold=None, full_rank=False):
    Result = pd.DataFrame()
    n, m = data.shape
    # 对数据编秩
    if full_rank:
        for i, X in enumerate(data.columns):
            Result[f'X{str(i + 1)}:{X}'] = data.iloc[:, i]
            Result[f'R{str(i + 1)}:{X}'] = data.iloc[:, i].rank(method="average")   # 整次编制
    else:
        for i, X in enumerate(data.columns):
            Result[f'X{str(i + 1)}:{X}'] = data.iloc[:, i]
            Result[f'R{str(i + 1)}:{X}'] = 1 + (n - 1) * (data.iloc[:, i] - data.iloc[:, i].min()) / (
                        data.iloc[:, i].max() - data.iloc[:, i].min())              # 非整次编制,正向指标
    # 计算秩和比
    weight = 1 / m if weight is None else np.array(weight) / sum(weight)
    Result['RSR'] = (Result.iloc[:, 1::2] * weight).sum(axis=1) / n  # axis=1,将每一行的元素相加
                                                                     # 加权的RSR
    Result['RSR_Rank'] = Result['RSR'].rank(ascending=False)         # RSR值的排序
    # 绘制 RSR 分布表
    RSR = Result['RSR']
    RSR_RANK_DICT = dict(zip(RSR.values, RSR.rank().values))
    Distribution = pd.DataFrame(index=sorted(RSR.unique()))   # 编号
    Distribution['f'] = RSR.value_counts().sort_index()       # 频数
    Distribution['Σ f'] = Distribution['f'].cumsum()          # 累计频数
    Distribution['Rf'] = [RSR_RANK_DICT[i] for i in Distribution.index]  #
    Distribution['R/n*100%'] = Distribution['Rf'] / n  # 根据累计频数算累计频率
    Distribution.iat[-1, -1] = 1 - 1 / (4 * n)  # 修正最后一项累计频率
    Distribution['Probit'] = 5 - scipy.stats.norm.isf(Distribution.iloc[:, -1])  # inverse survival function 将累计频率换算为概率单位
    print(Distribution)
    # 计算回归方差并进行回归分析
    r0 = np.polyfit(Distribution['Probit'], Distribution.index, deg=1)  # x,y
    model = sm.OLS(Distribution.index, sm.add_constant(Distribution['Probit']))  # y,x
    result = model.fit()
    print(result.summary())
    # 残差检验
    z_error, p_error = scipy.stats.normaltest(
        result.resid.values)  # tests the null hypothesis that a sample comes from a normal distribution
    print("残差分析:    ", p_error)

    if r0[1] > 0:
        print(f"\n回归直线方程为:y = {r0[0]} Probit + {r0[1]}")
    else:
        print(f"\n回归直线方程为:y = {r0[0]} Probit - {abs(r0[1])}")
    # 代入回归方程并分档排序
    Result['Probit'] = Result['RSR'].apply(lambda item: Distribution.at[item, 'Probit'])
    Result['RSR Regression'] = np.polyval(r0, Result['Probit'])
    C_level=scipy.stats.norm.ppf(0.3) + 5
    B_level=scipy.stats.norm.ppf(0.8)+5
    A_level=10
    threshold = np.polyval(r0, [0, C_level, B_level, A_level]) if threshold is None else np.polyval(r0, threshold)
    Result['Level'] = pd.cut(Result['RSR Regression'], threshold,
                             labels=range(len(threshold) - 1, 0, -1))  # Probit分组[(2, 4] < (4, 6] < (6, 8]]
    # 方差齐性检验
    x1=Result.loc[Result["Level"]==1,"RSR Regression"]
    x2 = Result.loc[Result["Level"] == 2, "RSR Regression"]
    x3 = Result.loc[Result["Level"] == 3, "RSR Regression"]
    stat, p = scipy.stats.bartlett(x1, x2, x3)
    print(stat, p)
    print(Counter(Result["Level"]))
    print(Result)

    return Result, Distribution
def rsrAnalysis(data, file_name=None, **kwargs):
    Result, Distribution = rsr(data, **kwargs)
    file_name = 'RSR 分析结果报告.xlsx' if file_name is None else file_name + '.xlsx'
    Excel_Writer = pd.ExcelWriter(file_name)
    Result.to_excel(Excel_Writer, '综合评价结果')
    Result.sort_values(by='Level', ascending=False).to_excel(Excel_Writer, '分档排序结果')
    Distribution.to_excel(Excel_Writer, 'RSR分布表')
    Excel_Writer.save()

data=pd.read_csv("已清理数据问一.csv")   # 默认将第一行认定为列名
# print(data.columns)
data_new=data[["总里程","运输时长","业务类型","运输等级","计划发车时间","车辆吨位","需求紧急程度","需求类型2"]]
# 将data成本类指标转化为效益类
data_new.loc[:,"业务类型"]=1/data_new.loc[:,"业务类型"]
data_new.loc[:,"运输等级"]=1/data_new.loc[:,"运输等级"]

rsr(data_new,weight=[0.359, 0.168, 0.075, 0.035, 0.065, 0.194, 0.087, 0.017])
rsrAnalysis(data_new,weight=[0.359, 0.168, 0.075, 0.035, 0.065, 0.194, 0.087, 0.017])

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值