精华内容
下载资源
问答
  • python计算平均数、众数、中位数、极差、方差、标准差……
    千次阅读
    2020-08-27 23:03:54

    第一步:加载数据源-手动输入需要统计的数据

    def num(a):
        if float(a) == int(a):
            return int(a)
        return float(a)
    #添加数据
    li = []
    print("请逐条添加数据!  (若退出请输入0000)")
    while True:
        print("请输入:")
        x = input()
        if x == "0000":
            break
        li.append(num(float(x)))
    

    第二步:计算统计指标

    """
    功能一:最大值、最小值、总和
    """
    print("最大值:",max(li))
    print("最小值:",min(li))
    print("总和:",sum(li))
    
    """
    功能二:平均数
    平均数,统计学术语,是表示一组数据集中趋势的量数,是指在一组数据中所有数据之和再除以这组数据的个数。
    它是反映数据集中趋势的一项指标。解答平均数应用题的关键在于确定“总数量”以及和总数量对应的总份数。
    """
    avg = sum(li) / len(li)
    print("平均数:",avg)
    
    """
    功能三:众数
    是一组数据中出现次数最多的数值,叫众数,有时众数在一组数中有好几个。
    """
    print(li)
    
    d = {}
    
    for i in li:
        ss = d.get(i)    
        if ss == None:
            d[i] = 1
        else:
            d[i] += 1
    
    for i in d.items():
        if i[1] == max(d.values()):
            print("众数:",i[0])
    
    """
    功能四:中位数
    对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,通常取最中间的两个数值的平均数作为中位数。
    """
    
    lis = sorted(li)
    if len(lis) % 2 == 1:
        print("中位数:",lis[int((len(lis) - 1) / 2)])
    else:
        print("中位数:",(lis[int(len(lis) / 2 - 1)] + lis[int(len(lis) / 2)]) / 2)
    
    """
    功能五:极差
    极差又称范围误差或全距(Range),以R表示,
    是用来表示统计资料中的变异量数(measures of variation),其最大值与最小值之间的差距,即最大值减最小值后所得之数据。
    """
    
    print("极差:",max(li) - min(li))
    
    """
    功能六:方差与标准差
    统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数。在许多实际问题中,研究方差即偏离程度有着重要意义。
    标准差(Standard Deviation) ,中文环境中又常称均方差,是离均差平方的算术平均数的平方根,用σ表示。标准差是方差的算术平方根。
    标准差能反映一个数据集的离散程度。平均数相同的两组数据,标准差未必相同。
    """
    
    sum1 = 0
    for i in li:
        sum1 += (i - avg) ** 2
    print("方差:",sum1 / len(li))
    print("标准差:",(sum1 / len(li)) ** (1 / 2))
    
    """
     方差越小越稳定。 例如,1.1.2.2,波动大,方差为0.25;而1.1.1.1,没有波动,方差就是0。 所以方差越小越稳定。
    """
    
    更多相关内容
  • //继续递归求解 调到前面的数(每组的中位数)的 "中位数" } 2、partition的实现 具体操作和上面描述的RandomizedSelect算法的partition的实现一样,就不重复赘述了,有需要看看上面具体说的。只是pivot是我们的...

    耐心整理的精品笔记,花点时间耐心看完,相信会有收获 ^_^ ) 

     

    本文目录

    解法一:RandomizedSelect算法

    一、算法描述

    1、分(divide)

    2、治(conquer)

    二、算法实现

    1、partition的实现

    2、RandomizedSelect的实现 

    完整代码:

    解法二:BFPTR算法

    1、选取pivot

    2、partition的实现

    3、BFPTR核心算法

    完整代码

    具体题目

    1、油井问题

     


    选择问题:找数组a的 [s, e] 范围内的第k小元素。同时,也就能求出中位数。

    • 解法一:RandomizedSelect算法期望O(n) 时间的选择算法。不稳定,会有比较差的O(n^2)时间出现。
    • 解法二:BFPTR算法最坏情况O(n) 时间的选择算法。理论上是最快的方法,最坏都是线性时间。

    两种算法都是通过分治的思想实现的, BFPTR算法可以说是RandomizedSelect算法的一种改进,写起来稍微麻烦一点。


    解法一:RandomizedSelect算法

    一、算法描述

    对数组a的 [s, e] 范围处理:

    1、分(divide)

    随机找到一个元素,记为pivot。然后将数组按照与pivot的大小关系分为两部分,分别分到pivot的两边。

    其实这个分边的操作有点像快排里面的partiton操作,只是我们的pivot是随机选取的。为了方便,我们选取最后一个元素a[e]为pivot,具体操作如下图所示:

     具体如何移动和实现的,之后会具体说。

    2、治(conquer)

    现在数组已经分好了,pivot所在位置的下标记为pivot_index,那么在pivot左侧(包括pivot)一共有 pivot_index - s + 1 个元素,记为num。然后判断,第k小元素在哪个部分:

    1. 刚好是pivot:直接返回pivot就行
    2. 在pivot左侧:对pivot左侧的元素 —— 数组a的 [s, pivot_index - 1] 递归地找第k小元素
    3. 在pivot右侧:对pivot右侧的元素 —— 数组a的 [pivot_index + 1, e] 递归地找第k - num 小元素

    二、算法实现

    1、partition的实现

    pivot选取为a[e],取两个游标 i、j 分别起始指向下标 s 和 e - 1。分别向中间推进,当 i 指向一个大于 pivot 值时停下,当 j 指向一个小于 pivot 值时停下,然后将两者互换。直到 i > j 结束,然后将 pivot 换到合适位置。

    下面是具体操作的图解:

    主要注意:结束时的条件、pivot 最终移动到合适的位置。

    /* 将数组a的[s, e]范围,按照与pivot的大小关系,划分到pivot两侧 *
     * 返回pivot最终的下标
     * 注:pivot是随机选取的 */
    int RandomizedPartition(int a[], int s, int e) {
        int pivot = a[e]; //取最后一个元素为pivot来划分
        int i = s, j = e - 1;
        while (i < j) {
            while (a[i] <= pivot && i < e - 1)
                i++;
            while (a[j] >= pivot && j > s)
                j--;
            if (i < j)
                swap(a[i], a[j]);
        }
        swap(a[i], a[e]);  //将pivot移动到合适位置
        return i;
    }

    2、RandomizedSelect的实现 

    /* 找数组a[s, e]范围内的第k小元素 */
    int RandomizedSelect(int a[], int s, int e, int k) {
        int pivot_index = RandomizedPartition(a, s, e); //按照与pivot的大小关系,划分到pivot两侧。返回pivot最终的下标
        int num = pivot_index - s + 1; //pivot(包括在内)左侧的元素个数
    
        if (num == k)//第k小元素恰好是pivot
            return a[pivot_index];
        else if (k < num)   //在pivot左边找
            return RandomizedSelect(a, s, pivot_index - 1, k);
        else  //在pivot右边找
            return RandomizedSelect(a, pivot_index + 1, e, k - num);
    }
    

    完整代码:

    /* 找数组a[s, e]范围内的第k小元素
     * 特殊情况:中位数... */
    
    #include <algorithm>
    using namespace std;
    
    /* 将数组a的[s, e]范围,按照与pivot的大小关系,划分到pivot两侧 *
     * 返回pivot最终的下标
     * 注:pivot是随机选取的 */
    int RandomizedPartition(int a[], int s, int e) {
        int pivot = a[e]; //取最后一个元素为pivot来划分
        int i = s, j = e - 1;
        while (i < j) {
            while (a[i] < pivot)
                i++;
            while (a[j] > pivot)
                j--;
            if (i < j)
                swap(a[i], a[j]);
        }
        swap(a[i], a[e]);  //将pivot移动到合适位置
        return i;
    }
    
    /* 找数组a[s, e]范围内的第k小元素 */
    int RandomizedSelect(int a[], int s, int e, int k) {
        int pivot_index = RandomizedPartition(a, s, e); //按照与pivot的大小关系,划分到pivot两侧。返回pivot最终的下标
        int num = pivot_index - s + 1; //pivot(包括在内)左侧的元素个数
    
        if (num == k)//第k小元素恰好是pivot
            return a[pivot_index];
        else if (k < num)   //在pivot左边找
            return RandomizedSelect(a, s, pivot_index - 1, k);
        else  //在pivot右边找
            return RandomizedSelect(a, pivot_index + 1, e, k - num);
    }
    
    int main() {
        int a[10] = {0, 9, 32, -2, 23, 33, 5, 1, 12, 76};
        printf("中位数:%d\n", RandomizedSelect(a, 0, 9, 10 / 2)); //测试输出中位数(小)
        printf("最大数:%d\n", RandomizedSelect(a, 0, 9, 1)); //测试输出最大数
        printf("最小数:%d\n", RandomizedSelect(a, 0, 9, 10)); //测试输出最小数
        printf("%d\n", RandomizedSelect(a, 0, 9, 7)); //其他测试
    }

     


    解法二:BFPTR算法

    其实RandomizedSelect算法会出现比较差的时间的原因就是:由于pivot是随机选取的,paritition分的不够均匀,导致算法会低效。那么BFPTR算法其实就是在这个问题上改进而来的:我们将pivot选取为一个相对来说靠中间的量,使得partition分配后pivot两侧元素个数差别不多。


    1、选取pivot

          既然两个算法的差别就是pivot的选取,那么pivot怎么找呢?通过验证(略,具体看算法书),这样子是最合适的:将数组a的 [s, e] 分组,5个一组,最终不足5个的也分到一组。分别每组进行选择排序,同时能找出每组的中位数,将这些中位数抽出,继续在这些中位数中找"中位数"。

      🔺 注意! 

          很多算法书上面描述的是找中位数的中位数,其实有些费解,我看了很多资料才明白,这应该是中文书翻译的锅(吐了)。其实应该这样子表述:找中位数的"中位数",第一个中位数不打引号,是因为确实是每组的中位数的集合;第二个中位数打上了引号,是因为它最后找出的不是真正的中位数,只是一个相对靠中间的数。

      🔺 如何理解呢?

          因为每次将每组的中位数抽出来继续寻找"中位数",这是一个递归的调用。递归的终点是什么?是最终传入的数组只能分为一组(也就是不超过五个元素),那么这时直接返回第一个元素(不要问为啥,就是近似嘛,可以验证这是合理的)。

         所以说,pivot是一个近似的中位数,而非真正的中位数有这两个原因:

    1. 每组中位数的中位数不一定就是整体的中位数
    2. 况且递归的终点也是近似的,随机找的第一个元素嘛

         理解了pivot如何选取,就可以直接上代码了:

    /* 在数组a的[s, e]范围内找到一个大致的"中位数" */
    int FindMid(int a[], int s, int e) {
        int cnt = 0; //实时记录分组的编号(从零依次)
        int i;
        /* 五数一组,每组排序后找到中位数,调换到a数组前列 */
        for (i = s; i + 4 <= s; i += 5) {
            InsertSort(a, i, i + 4);  //排序
            swap(a[s + cnt], a[i + 2]); //将中位数调换到a数组前第cnt个
            cnt++;  //小组增加一个
        }
        /* 处理剩余元素 */
        if (i < e) {
            InsertSort(a, i, e); //排序
            swap(a[s + cnt], a[(i + e) / 2]); //将中位数调换到a数组前第cnt个
            cnt++;
        }
    
        if (cnt <= 1)  //递归的终点:只有一个/没有分组的时候
            return a[s];
        return FindMid(a, s, s + cnt - 1);  //继续递归求解 调到前面的数(每组的中位数)的 "中位数"
    }

    2、partition的实现

           具体操作和上面描述的RandomizedSelect算法的partition的实现一样,就不重复赘述了,有需要看看上面具体说的。只是pivot是我们的FindMid函数计算出来的。有一点小区别要注意:为了方便移动,pivot需要我们自己最先移动到a[e]位置,最后再移动回合适位置。

          另外有一种特殊情况要注意,就是当序列不需要调整时(pivot为最大元素),应单独考虑。

          具体代码如下:

    /* 将数组a的[s, e]范围,按照与pivot的大小关系,划分到pivot两侧 *
     * 返回pivot最终的下标 */
    int partition(int a[], int s, int e, int pivot) {
        int p = FindIndex(a, s, e, pivot);  //找到pivot的下标
        swap(a[p], a[e]);  //将pivot换到最末端
        int i = s, j = e - 1;
        while (i < j) {
            while (a[i] <= pivot)
                i++;
            while (a[j] >= pivot)
                j--;
            if (i < j)
                swap(a[i], a[j]);
        }
        if(a[i] < pivot)   //所有元素都比pivot小,原序列不需要调整
            return e;
        else {
            swap(a, i, e);   //将pivot转到合适位置
            return i;
        }
    }
    

    3、BFPTR核心算法

          具体操作和上面描述的RandomizedSelect算法的实现一样是一样的,就不重复赘述了,有需要看看上面具体说的。

    /* 找数组的[s, e]范围内第k小元素 */
    int BFPTR(int a[], int s, int e, int k) {
        int pivot = FindMid(a, s, e);  //找到一个大致的"中位数"
        int pivot_index = partition(a, s, e, pivot);  //按照与pivot的大小关系,划分到pivot两侧。返回pivot最终的下标
        int num = pivot_index - s + 1;  //pivot(包括在内)左侧的元素个数
    
        if (num == k)//第k小元素恰好是pivot
            return pivot;
        else if (k < num)   //在pivot左边找
            return BFPTR(a, s, pivot_index - 1, k);
        else  //在pivot右边找
            return BFPTR(a, pivot_index + 1, e, k - num);
    }

    完整代码

    // Created by A on 2020/2/26.
    
    /* 找数组a[s, e]范围内的第k小元素
     * 特殊情况:中位数...
     * 最差时间复杂度为线性 O(N)*/
    
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    /* 增序的插入排序
     * 对数组a的[s, e]范围排序 */
    void InsertSort(int a[], int s, int e) {
        for (int i = s + 1; i <= e; i++) {
            int temp = a[i];  //取出待插入元素
            int t = i;  //待插入的位置
            /* 当待插入元素 小于 待插入位置的前一个元素 */
            while (t > 0 && temp < a[t - 1]) {
                a[t] = a[t - 1];  //将前一个元素后移
                t--;  //待插入位置前移
            }
            a[t] = temp;  //插入合适位置
        }
    }
    
    /* 在数组a的[s, e]范围内找到一个大致的"中位数" */
    int FindMid(int a[], int s, int e) {
        int cnt = 0; //实时记录分组的编号(从零依次)
        int i;
        /* 五数一组,每组排序后找到中位数,调换到a数组前列 */
        for (i = s; i + 4 <= s; i += 5) {
            InsertSort(a, i, i + 4);  //排序
            swap(a[s + cnt], a[i + 2]); //将中位数调换到a数组前第cnt个
            cnt++;  //小组增加一个
        }
        /* 处理剩余元素 */
        if (i < e) {
            InsertSort(a, i, e); //排序
            swap(a[s + cnt], a[(i + e) / 2]); //将中位数调换到a数组前第cnt个
            cnt++;
        }
    
        if (cnt <= 1)  //递归的终点:只有一个/没有分组的时候
            return a[s];
        return FindMid(a, s, s + cnt - 1);  //继续递归求解 调到前面的数(每组的中位数)的 "中位数"
    }
    
    /* 找到数组a的[s, e]范围内 key对应的下标 */
    int FindIndex(int a[], int s, int e, int key) {
        for (int i = s; i <= e; i++) {
            if (a[i] == key)
                return i;
        }
    }
    
    /* 将数组a的[s, e]范围,按照与pivot的大小关系,划分到pivot两侧 *
     * 返回pivot最终的下标 */
    int partition(int a[], int s, int e, int pivot) {
        int p = FindIndex(a, s, e, pivot);  //找到pivot的下标
        swap(a[p], a[e]);  //将pivot换到最末端
        int i = s, j = e - 1;
        while (i < j) {
            while (a[i] <= pivot)
                i++;
            while (a[j] >= pivot)
                j--;
            if (i < j)
                swap(a[i], a[j]);
        }
        swap(a[e], a[i]); //将pivot移动到合适位置
        return i;
    }
    
    /* 找数组的[s, e]范围内第k小元素 */
    int BFPTR(int a[], int s, int e, int k) {
        int pivot = FindMid(a, s, e);  //找到一个大致的"中位数"
        int pivot_index = partition(a, s, e, pivot);  //按照与pivot的大小关系,划分到pivot两侧。返回pivot最终的下标
        int num = pivot_index - s + 1;  //pivot(包括在内)左侧的元素个数
    
        if (num == k)//第k小元素恰好是pivot
            return pivot;
        else if (k < num)   //在pivot左边找
            return BFPTR(a, s, pivot_index - 1, k);
        else  //在pivot右边找
            return BFPTR(a, pivot_index + 1, e, k - num);
    }
    
    int main() {
        int a[10] = {0, 9, 32, -2, 23, 33, 5, 1, 12, 76};
        printf("中位数:%d\n", BFPTR(a, 0 , 9, 10 / 2)); //测试输出中位数(小)
        printf("最大数:%d\n", BFPTR(a, 0 , 9, 1)); //测试输出最大数
        printf("最小数:%d\n", BFPTR(a, 0 , 9, 10)); //测试输出最小数
        printf("%d\n", BFPTR(a, 0 , 9, 7)); //其他测试
    }

    具体题目

    1、油井问题

     

    成绩10开启时间2020年02月25日 星期二 08:55
    折扣0.8折扣时间2020年04月30日 星期四 23:55
    允许迟交关闭时间2020年04月30日 星期四 23:55

     

    主油管道为东西向,确定主油管道的南北位置,使南北向油井喷油管道和最小。要求线性时间完成。

    油井

    1<= 油井数量 <=2 000 000

    输入要求:

    输入有油井数量行,第 K 行为第 K 油井的坐标 X ,Y 。其中, 0<=X<2^31,0<=Y<2^31 。

    输出要求:

    输出有一行, N 为主管道最优位置的最小值

    注意:用快排做的不给分!!

     

    友情提示:可以采用while(scanf("%d,%d",&x,&y) != EOF)的数据读入方式。

     测试输入期待的输出时间限制内存限制额外进程
    测试用例 1以文本方式显示
    1. 41,969978↵
    2. 26500,413356↵
    3. 11478,550396↵
    4. 24464,567225↵
    5. 23281,613747↵
    6. 491,766290↵
    7. 4827,77476↵
    8. 14604,597006↵
    9. 292,706822↵
    10. 18716,289610↵
    11. 5447,914746↵
    以文本方式显示
    1. 597006↵
    1秒64M0

    本题的x坐标是没有意义的,仔细想想应该知道,最终是需要找出y坐标的中位数才是油管的最佳位置。既然说不能用快排直接找出中位数,那么就可以通过上面的算法来寻找中位数。

    我是用BFPTR来实现的,会比较快,完整AC代码如下

    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    const int N = 2000005;
    
    int a[N];
    
    /* 增序的插入排序
     * 对数组a的[s, e]范围排序 */
    void InsertSort(int a[], int s, int e) {
        for (int i = s + 1; i <= e; i++) {
            int temp = a[i];  //取出待插入元素
            int t = i;  //待插入的位置
            /* 当待插入元素 小于 待插入位置的前一个元素 */
            while (t > 0 && temp < a[t - 1]) {
                a[t] = a[t - 1];  //将前一个元素后移
                t--;  //待插入位置前移
            }
            a[t] = temp;  //插入合适位置
        }
    }
    
    /* 在数组a的[s, e]范围内找到一个大致的"中位数" */
    int FindMid(int a[], int s, int e) {
        int cnt = 0; //实时记录分组的编号(从零依次)
        int i;
        /* 五数一组,每组排序后找到中位数,调换到a数组前列 */
        for (i = s; i + 4 <= s; i += 5) {
            InsertSort(a, i, i + 4);  //排序
            swap(a[s + cnt], a[i + 2]); //将中位数调换到a数组前第cnt个
            cnt++;  //小组增加一个
        }
        /* 处理剩余元素 */
        if (i < e) {
            InsertSort(a, i, e); //排序
            swap(a[s + cnt], a[(i + e) / 2]); //将中位数调换到a数组前第cnt个
            cnt++;
        }
    
        if (cnt <= 1)  //递归的终点:只有一个/没有分组的时候
            return a[s];
        return FindMid(a, s, s + cnt - 1);  //继续递归求解 调到前面的数(每组的中位数)的 "中位数"
    }
    
    /* 找到数组a的[s, e]范围内 key对应的下标 */
    int FindIndex(int a[], int s, int e, int key) {
        for (int i = s; i <= e; i++) {
            if (a[i] == key)
                return i;
        }
    }
    
    /* 将数组a的[s, e]范围,按照与pivot的大小关系,划分到pivot两侧 *
     * 返回pivot最终的下标 */
    int partition(int a[], int s, int e, int pivot) {
        int p = FindIndex(a, s, e, pivot);  //找到pivot的下标
        swap(a[p], a[e]);  //将pivot换到最末端
        int i = s, j = e - 1;
        while (i < j) {
            while (a[i] <= pivot)
                i++;
            while (a[j] >= pivot)
                j--;
            if (i < j)
                swap(a[i], a[j]);
        }
        swap(a[e], a[i]); //将pivot移动到合适位置
        return i;
    }
    
    /* 找数组的[s, e]范围内第k小元素 */
    int BFPTR(int a[], int s, int e, int k) {
        int pivot = FindMid(a, s, e);  //找到一个大致的"中位数"
        int pivot_index = partition(a, s, e, pivot);  //按照与pivot的大小关系,划分到pivot两侧。返回pivot最终的下标
        int num = pivot_index - s + 1;  //pivot(包括在内)左侧的元素个数
    
        if (num == k)//第k小元素恰好是pivot
            return pivot;
        else if (k < num)   //在pivot左边找
            return BFPTR(a, s, pivot_index - 1, k);
        else  //在pivot右边找
            return BFPTR(a, pivot_index + 1, e, k - num);
    }
    
    
    int main() {
        int x, y[N], n = 0;
        while (EOF != scanf("%d,%d", &x, &y[n]))
            n++;
        printf("%d\n", BFPTR(y, 0, n - 1, (n + 1) / 2));
    
    }

    结果还是比较理想的,算是比较快:

     



    end 

    欢迎关注个人公众号 鸡翅编程 ”,这里是认真且乖巧的码农一枚。

    ---- 做最乖巧的博客er,做最扎实的程序员 ----

    旨在用心写好每一篇文章,平常会把笔记汇总成推送更新~

     

    在这里插入图片描述

    展开全文
  • print("中位数:",(lis[int(len(lis) / 2 - 1)] + lis[int(len(lis) / 2)]) / 2) 功能五:极差 极差又称范围误差或全距(Range),以R表示,是用来表示统计资料中的变异量数(measures of variation),其最大值与...

    Python代码实现

    第一步:添加数据到列表
    def num(a):
        if float(a) == int(a):
            return int(a)
        return float(a)
    #添加数据
    li = []
    print("请逐条添加数据!  (若退出请输入0000)")
    while True:
        print("请输入:")
        x = input()
        if x == "0000":
            break
        li.append(num(float(x)))
    

    其中,num() 为自定义函数,用于取整,即在不影响数值的情况下,去掉小数点后的 0
    以上代码用于添加一组数据。

    功能一:最大值、最小值、总和
    print("最大值:",max(li))
    print("最小值:",min(li))
    print("总和:",sum(li))
    
    功能二:平均数

    平均数,统计学术语,是表示一组数据集中趋势的量数,是指在一组数据中所有数据之和再除以这组数据的个数。它是反映数据集中趋势的一项指标。解答平均数应用题的关键在于确定“总数量”以及和总数量对应的总份数。

    avg = sum(li) / len(li)
    print("平均数:",avg)
    
    功能三:众数

    是一组数据中出现次数最多的数值,叫众数,有时众数在一组数中有好几个。

    d = {}
    for i in li:
        ss = d.get(i)
        if ss == None:
            d[i] = 1
        else:
            d[i] += 1
    for i in d.items():
        if i[1] == max(d.values()):
            print("众数:",i[0])
    

    其中,d 为字典,用于存储各个数据出现的次数,字典的键为数据,值为次数。

    功能四:中位数

    对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,通常取最中间的两个数值的平均数作为中位数。

    lis = sorted(li)
    if len(lis) % 2 == 1:
        print("中位数:",lis[int((len(lis) - 1) / 2)])
    else:
        print("中位数:",(lis[int(len(lis) / 2 - 1)] + lis[int(len(lis) / 2)]) / 2)
    
    功能五:极差

    极差又称范围误差或全距(Range),以R表示,是用来表示统计资料中的变异量数(measures of variation),其最大值与最小值之间的差距,即最大值减最小值后所得之数据。

    print("极差:",max(li) - min(li))
    
    功能六:方差与标准差

    统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数。在许多实际问题中,研究方差即偏离程度有着重要意义。
    标准差(Standard Deviation) ,中文环境中又常称均方差,是离均差平方的算术平均数的平方根,用σ表示。标准差是方差的算术平方根。标准差能反映一个数据集的离散程度。平均数相同的两组数据,标准差未必相同。

    sum1 = 0
    for i in li:
        sum1 += (i - avg) ** 2
    print("方差:",sum1 / len(li))
    print("标准差:",(sum1 / len(li)) ** (1 / 2))
    
    以上所有代码的运行效果:


    希望这些功能能对大家起到帮助!

    博主推荐

    n阶行列式求解

    展开全文
  • 为了剪除实际意义上冗余的filters,文章提出了基于几何中位数的剪枝策略( FPGM: Filter Pruning via Geometric Median ),认为那些位于或接近几何中位数的filters包含了冗余信息( redundant information )、都是...

    "Filter Pruning via Geometric Median for Deep Convolutional Neural Networks Acceleration" 这篇文章开门见山地指出了"smaller-norm-less-important"剪枝策略的不足,即通常需要满足两个前提条件:1)首先要求filter norm数据分布的偏差足够大,确保在宽泛的分布区间内,通过阈值化处理能够有效分离数据;2)其次要求被剪除的filters的norm足够小,并对网络推理精度的贡献也足够小,确保裁剪掉这些filters之后,对网络精度不会造成存在较大影响。为了剪除实际意义上冗余的filters,文章提出了基于几何中位数的剪枝策略(FPGM: Filter Pruning via Geometric Median),认为那些位于或接近几何中位数的filters包含了冗余信息(redundant information)、都是最可被替代的(the most replaceable contribution),因此可以被有效剪除、并用剩余filters替代。相比于norm-based剪枝策略,当前述两个前提条件不能全部满足时,基于几何中位数的剪枝策略也能获得理想的模型压缩表现。

    norm-based剪枝策略与基于几何中位数的剪枝策略的比较如下图所示。在符合两个前提条件时,norm-based剪枝策略仅保留大norm的filters,并能获得理想的剪枝效果;而基于几何中位数的剪枝策略主要移除靠近几何中位数的冗余filters,一些norm小的filters也有可能保留下来:

    在实际情况下,两个前提条件通常较难满足,下图分别反映了small norm deviation与large minimum norm两种情形:当norm分布偏差较小时,norm数值主要集中在较小的区间范围内,导致较难选择合适的阈值用于剪枝;当最小norm的数值不够小时,norm低于阈值的filters仍对网络性能有一定的贡献、具备一定的信息量,因此剪除这些filters将对网络性能带来负面影响。

    Geometric Median: 在d维空间内,与n个点的欧式距离之和最小的点,称之为几何中位数点,具体定义如下:

    文章使用第i层所有filters的几何中位数,作为该层的信息估计或数据中心:

    式中g(x)表示张量x与第i层所有filters的欧氏距离之和:

    基于Geometric Median的剪枝策略(FPGM),其基本思想是:若第i层中存在与几何中位数相接近的filters,则这些filters是信息冗余的,可以被剩余filters替代。并且,剪除这些冗余的filters不会对网络性能造成较大影响。这些冗余filters估计如下:

    为了快速求解Geometric Median,文章假设位于第i层的filters中:

    如此,式(2)变为如下优化问题,即在所有filters中寻找一个filter,确保其与剩余filters的欧氏距离之和最小:

    根据式(5)与(6),几何中位数的计算没必要将包含在内,因此可获得几何中位数估计的等价形式:

    式(6)与式(8)的关系,可表示如下:

    式(9)两侧同时取min运算,并结合式(5)的近似假设(几何中位数位于filters中),可获得如下近似推导:

    由于,因此:

    上述推导过程表明,包含与不包含的filters,其数据中心是一样的。因此位于或靠近几何中位数的filters,是信息冗余的,可以被剩余filters替代。

    基于Geometric Median的剪枝算法如下所示,类似于Soft Filter Pruning的实施过程:在训练过程中的第t个epoch,首先更新网络参数,然后根据每层的Geometric Median以及预先设定的剪枝率,将冗余的filters置零;置零的filters,在下一个epoch重新接受参数更新;如此反复迭代,最终冗余的filters将趋于稀疏化,达到正则化的目的。

    理论上,通过削减卷积层的输入/输出通道数,可以获得可观的压缩比与加速比,但实际的加速效果也受除卷积之外的其他操作、以及计算资源、访存和IO延迟等因素的影响。

    实验结果具体见文章实验部分,值得注意的是:将式(3)中的欧氏距离替换为L1-norm或cosine距离的影响(L1 norm能够轻微改善效果,而cosine距离则轻微损害效果),以及FPGM与Norm-based剪枝策略的联合使用(针对简单任务如CIFAR-10,两个前提条件在有些网络层得到满足,因此结合Norm-based剪枝策略能够改善效果,但针对复杂任务如ImageNet,则较难满足)。

    Paper地址:https://arxiv.org/abs/1811.00250

    GitHub地址(PyTorch):https://github.com/he-y/filter-pruning-geometric-median

    展开全文
  • 方格”是笨方法吗?

    千次阅读 2021-02-12 05:23:49
    方格”是笨方法吗?深圳市宝安区西乡街道教学研究中心张维国在学习与探索平行四边形、三角形等基本图形的面积计算之前,教材安排了“比较图形的面积”活动(如右图)。教材的本意是以方格纸为载体,让学生自主地...
  • 求解属性值权重,从区间直觉模糊的几何意义出发,基于熵值最大化原理,求出属性的权重,得到每专家对每个方案的综合评价值。基于专家个体与专家群体意见之间的灰色关联度以及熵最大化原理,建立模型求出各决策...
  • 最优化问题求解之:遗传算法

    千次阅读 2021-07-27 09:14:20
    遗传算法的手工模拟计算示例为更好地理解遗传算法的运算过程,下面用手工计算来简单地模拟遗传...因 x1, x2 为 0 ~ 7之间的整数,所以分别用3无符号二进制整数来表示,将它们连接在一起所组成的6无符号二进制...
  • Top-K问题的几种求解方法

    千次阅读 2018-05-05 11:14:31
    HeapSelect求解方法 使用这种方法求解,需要借助一种数据结构叫做堆。这里我们使用的是小根堆。 首先把数组的前k个值用来建一个小根堆。 之后的其他拿到之后进行判断,如果遇到比小顶堆的堆顶的值大的,将它...
  • 文章目录问题求解Agent问题形式化通过搜索求解(树搜索、图搜索)无信息搜索策略(盲目搜索)宽度优先搜索(广度优先搜索)(BFS)一致代价搜索(Uniform-cost Search)深度优先搜索(DFS)深度受限搜索(Depth Limited...
  • 求两个有序数组的中位数

    千次阅读 2014-11-25 20:24:06
    2、假设两个有序数组长度不等,同样的求出中位数。 一:解析: 这个题目看起来非常简单。第一题的话: 假设数组长度为n, 那么我就把数组1和数组2直接合并,然后再直接找到中间元素。对于这样的方案,第一题和第二题...
  • 遗传算法求解TSP旅行商问题

    千次阅读 2021-07-05 10:13:55
    旅行商问题是一个典型的组合优化问题,其可能的路径数目是与城市数目N呈指数型增长的,一般很难精确地求出其最优解,因而寻找其有效的近似求解算法具有重要的理论意义,特别是当N的数目很大时,用常规的方法求解计算量太...
  • 最大覆盖选址问题建模与求解

    千次阅读 多人点赞 2021-11-09 23:31:08
    建立容量、服务半径约束的最大覆盖选址问题模型,并设计禁忌搜索算法,使用python编程求解
  • 目录遗传算法求解3D打印零件二维排布问题(MATLAB实现)一、遗传算法简介二、排样方法1.二维不规则排样2.编码解码方式三、遗传算法求解1.算法建模2.遗传算子选择算子交叉算子变异算子四、实例MATLAB代码五、结语...
  • A为n阶矩阵,若λ和n维非0列向量x满足Ax=λx,那么λ称为A的特征值,x称为A的对应于特征值λ的特征向量。它的物理意义是:一个矩阵A乘以一个向量x,就相当于做了一个线性变换λx。方向仍然保持不变,只是拉伸...
  •  求解A-1除了之前的初等变换方法外,我们还可以通过代数余子式的方式求解。 余子式:在一个n阶行列式D,把元素aij (i,j=1,2,…..n)所在的行与列划去后,剩下的(n-1)^2个元素按照原来的次序组成的一个n-1阶行列式...
  • 相关问题在markdown,设置二级标题所用的符号是markdown 标题 符号以下说法正确的是___________原始陶器上的绘画和神秘符号具有哪些特点?( ): 原始陶器 上 绘画 符号 特点 形象性 装饰性 抽象性 意象性在社会...
  • 数据集中趋势 在统计研究,需要搜集大量数据并对其进行加工整理,大多数情况下数据都会呈现...根据统计学知识,集中趋势指平均,是一组数据有代表性的值,这些数值趋向于落在数值大小排列的数据中心,被称为...
  • 令人头疼的优化问题——多目标规划问题matlab求解

    千次阅读 热门讨论 2021-05-21 14:11:18
    今天我们要来解决一个运筹学较为头疼的问题,多目标规划问题。 1.多目标规划问题的描述 多目标问题可以描述成如下问题: 其中,fi(x)f_i(x)fi​(x)为待优化的目标函数;x为待优化的变量;lb和ub分别为变量x的...
  • 建立容量约束的p-中值选址问题模型,并设计禁忌搜索算法,使用python编程求解
  • 直接得出: 根据数组建立平衡二叉搜索树 java整体打印二叉树 判断平衡二叉树 判断完全二叉树 判断二叉搜索树 二叉搜索树实现 堆的简单实现 堆应用例题三连 一个数据流中,随时可以取得中位数。 金条 项目最大收益...
  • 分析了用干涉仪检测中心遮拦光学元件时仍采用圆泽尼克(Zernike)多项式表述相位和求解赛德尔像差的弊端,在环形域上,圆泽尼克多项式不再具有正交性和明确的物理意义。给出了环域泽尼克多项式的求解方式和表达形式,这些...
  • Matlab偏微分方程快速上手:使用pdetool工具箱求解二维偏微分方程,适用于数学建模、数学实验,简单的偏微分方程数值计算与工程问题。
  • 日前,来自中国自主研发的两款商业决策优化求解器软件成功登顶国际权威数学决策软件测评排行榜,杉科技拔得头筹,阿里紧随其后,引发了国人对于决策优化求解器的关注。此前,由于国际竞争,芯片和操作系统已经成为...
  • 行列式的几何意义、计算公式

    千次阅读 2021-03-21 21:03:41
    近期回顾了下行列式的计算方法,以及其几何意义,本文是作者的一点浅薄理解。欢迎朋友们一起交流。 线性代数系列文章见专栏,下面是往期内容: 为什么要学线性代数 (点击蓝色字体进入查看) 正题: 每一个线性...
  • 采用遗传算法求解函数最优值

    千次阅读 2020-12-10 22:00:42
    采用遗传算法求解函数最优值一、实验内容二、实验目的三、实验过程四、实验结果,程序运行结果五、结论六、实验心得七、源程序 ...熟悉对遗传算法的建模、求解及编程语言的应用。 三、实验过程 1.算法基本原理与流程图
  • 在一个数组找到第k小的(线性时间选择)

    千次阅读 多人点赞 2019-01-18 02:16:59
    在一个数组找到第k小的(线性时间选择) 在这一部分,我们讨论的题目为元素选择问题。这类题目的一般问法为:给定线性序集中n个元素和一个整数k,1 <= K <= n,要求找出这n个元素第k小的元素,如(1,4...
  • 求解线性同余方程--扩展欧几里得

    千次阅读 2018-08-07 10:31:12
    资料来源:https://blog.csdn.net/ //求解ax=b(mod m) 返回0为无解,否则返回gcd(a,m)个mod m意义下的解,用X[]存 int mod(int a, int b, int m) { return equation(a, m, b); } 先看一道题目: ...
  • 递归和迭代这两个概念也许很多童鞋依旧是老虎老鼠傻傻分不清楚,下面通过求解斐波那契来看看它们俩的关系吧。斐波那契的定义: f0=0 f_0 = 0 f1=1 f_1 = 1 fi=fi−1+fi−2(i>1) f_i = f_{i-1}+f_{i-2} (i > 1...
  • 【车间调度】遗传算法求解柔性作业车间调度问题

    千次阅读 多人点赞 2021-01-29 14:58:11
    本系列为自己学习调度相关知识的记录,如有误请指出,也欢迎调度方向的小伙伴加我好友共同交流。 FJSP的染色体编码 染色体编码是将所研究的问题的解用...染色体编码对求解速度、计算精度等有着直接的关系,对算法具.
  • 粒子群优化(PSO)是一种群智能算法,其灵感来自于鸟类的群集或鱼群学习,用于解决许多科学和工程领域出现的非线性、非凸性或组合优化问题。 1.1.1 算法思想 许多鸟类都是群居性的,并由各种原因形成不同的鸟群。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,252
精华内容 8,100
关键字:

中位数的意义及求解方法