Bootstrap

秩和检验python实现——基于常用的排序算法

秩和检验python实现——基于常用的排序算法

一、常用排序算法

仅介绍下文会用到的计数排序与快速排序

1.1、计数排序(Counting Sort)

【排序算法】计数排序 - 知乎 https://www.zhihu.com/zvideo/1519078487213854720

适用于数据量不大的非负整数排序,算法核心思想可参考上述链接,以下针对该图片示例进行说明:

  • 确定待排序数组中的最大值7,创建一个长度为7+1的数组(计数数组),初始值均为0;
  • 遍历待排序数组,确定各个数字的个数:其中数字3出现2次(count=2),则计数数组索引3的元素值为2;
  • 新建结果数组,遍历计数数组,按照出现次数(count)向结果数组中添加元素:其中0未出现,不添加,1出现1次,则结果数组中添加1个1。

在这里插入图片描述

def counting_sort(mylist):
    """
    计数排序(以空间换时间),适用于数据范围较集中的非负整数排序
    :param mylist: 待排序数组
    :return: 升序排列数组
    """
    sorted_list = []
    min_value = min(mylist)
    max_value = max(mylist)
    # 创建含有max_value-min_value+1个元素的列表(初始值均为0)
    # 能够减少内存占用,避免0-min_value之间的内存浪费(记录排序结果时注意偏移量为min_value)
    counting_list = [0] * (max_value - min_value + 1)
    # 记录各个元素的出现次数
    for i in mylist:
        counting_list[i - min_value] += 1
    for j in range(len(counting_list)):
        while counting_list[j] > 0:
            sorted_list.append(j + min_value)
            counting_list[j] -= 1

    return sorted_list

1.2、快速排序(Quick Sort)

【排序算法】:快速排序 - 程序员囧辉的文章 - 知乎 https://zhuanlan.zhihu.com/p/35946897

算法核心思想可参考上述链接,以下针对该图片示例进行说明:

  • 从要排序的数组中取一个数为“基准数”(取最左侧元素3);
  • 通过一趟排序(数组中其余元素均与“基准数”比较大小),将要排序的数据分割成两部分,其中左边的数据都比“基准数”小,右边的数据都比“基准数”大;
  • 然后再按步骤2对这两部分数据分别排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

第一趟排序的过程
一次
在这里插入图片描述

第一趟排序的结果,以及最终结果
在这里插入图片描述

def quick_sort(mylist, front, rear):
    """
    快速排序(对数组递归排序,需要首尾索引作为输入)
    :param mylist: 待排序数组
    :param front: 首索引(原数组mylist)
    :param rear: 尾索引(原数组mylist)
    :return: 排序后的数组
    """
    if front >= rear:
        return

    # 确定用于排序的阈值
    low = front
    high = rear
    # 以列表的第一个数值作为阈值
    threshold = mylist[front]
    # 根据选定的阈值进行一次排序(双指针结束条件):调整mylist中的元素位置左边的数都小于阈值,右边的数都大于阈值
    while front < rear:
        while front < rear and mylist[rear] >= threshold:
            rear -= 1
        if front < rear:
            mylist[front] = mylist[rear]
            front += 1

        while front < rear and mylist[front] <= threshold:
            front += 1
        if front < rear:
            mylist[rear] = mylist[front]
            rear -= 1
    mylist[front] = threshold
    quick_sort(mylist, low, front)
    quick_sort(mylist, front + 1, high)
    return mylist

二、秩和检验

2.1、理论知识

参考链接:https://wiki.mbalib.com/wiki/%E7%A7%A9%E5%92%8C%E6%A3%80%E9%AA%8C

秩和检验是一种非参数检验法, 它是一种用样本秩来代替样本值的检验法

  • 用秩和检验可以检验两个总体的分布函数是否相等;
  • 如果两个样本来自两个独立的但非正态或形态不清的总体,要检验两样本之间的差异是否显著,不应运用参数检验中的“T检验”,而需采用秩和检验。

秩:升序排列后,元素在序列中的位次(位次从1开始),相等的元素取位次均值作为秩

秩和:各个元素的秩相加

  • 举例:对于排序后的序列0,1,1,2,元素0的秩为1,元素1的秩为(2+3)/2=2.5,元素2的秩为4,该序列的秩和为10

2.2、代码详解

def rank_sum_test(list_one, list_two):
    """
    秩和检验:计算用于判断两组样本差异显著性的Z值
    两个样本的容量均小于10时,计算样本量小的样本的秩和,查表确定差异是否显著
    两个样本的容量均大于10时,采用该函数计算Z值,据此确定差异是否显著
    :param list_one: 数组1
    :param list_two: 数组2
    :return: Z值
    """
    # 合并数组
    all_sample = list_one + list_two
    # 调用排序算法,得到升序排列的数组
    all_sample_sorted = quick_sort(all_sample, 0, len(all_sample) - 1)
    # 计算数组中元素的秩
    rank_dic = {}
    i = 0
    while i < len(all_sample_sorted):
        sample = all_sample_sorted[i]
        j = i + 1
        # 最后一个元素
        if j == len(all_sample_sorted):
            rank_dic[sample] = (i + 1 + j) / 2
            break

        # 元素是否相等
        while all_sample_sorted[j] == all_sample_sorted[i]:
            j += 1
        # 若有多个数值相等,则取均值作为秩(化简得到下式)
        # [1,2,2,3],则“1”的秩为1,2的秩为(2+3)/2=2.5
        rank_dic[sample] = (i + 1 + j) / 2
        # 修改索引,保证相等的数值有同样的秩
        i = j

    # 确定样本数量少的秩和、样本数
    T_list = list_one if len(list_one) < len(list_two) else list_two
    n1 = len(T_list)

    T = 0
    for i in T_list:
        T += rank_dic[i]

    # 根据公式计算Z值(两个样本容量均大于10时)
    z_value = (T - (n1 * (len(list_one) + len(list_two) + 1)) / 2) / math.sqrt((len(list_one) * len(list_two) * (len(list_one) + len(list_two) + 1)) / 12)

    return z_value

三、相关链接

  1. 代码文件:
    https://download.csdn.net/download/weixin_42639395/88071829?spm=1001.2014.3001.5503

  2. 【排序算法】计数排序 - 知乎 https://www.zhihu.com/zvideo/1519078487213854720

  3. 【排序算法】:快速排序 - 程序员囧辉的文章 - 知乎 https://zhuanlan.zhihu.com/p/35946897

  4. 秩和检验:https://wiki.mbalib.com/wiki/%E7%A7%A9%E5%92%8C%E6%A3%80%E9%AA%8C

;