精华内容
下载资源
问答
  • 2021-03-17 02:26:22

    这一篇博客保证是我写的最清楚,最容易理解的博客!!

    众所周知,sum不传参的时候,是所有元素的总和。这里就不说了。

    1 sum函数可以传入一个axis的参数,这个参数怎么理解呢?这样理解:

    假设我生成一个numpy数组a,如下

    >>> import numpy as np

    >>> a = np.array([[[1,2,3,2],[1,2,3,1],[2,3,4,1]],[[1,0,2,0],[2,1,2,0],[2,1,1,1]]])

    >>> a

    array([[[1, 2, 3, 2],

    [1, 2, 3, 1],

    [2, 3, 4, 1]],

    [[1, 0, 2, 0],

    [2, 1, 2, 0],

    [2, 1, 1, 1]]])

    >>>

    这是一个拥有两维的数组,每一维又拥有三个数组,这个数组里面拥有四个元素。如果我们要将这个a数组中的第一个元素1定位出来,则我们会输入a[0][0][0]。好,这个axis的取值就是这个精确定位某个元素需要经过多少数组的长度,在这里是3,,所以axis的取值有0,1,2。如果一个数组精确到某个元素需要a[n0][n1][n2][...][n],则axis的取值就是n。定位 到这里,axis的参数的取值就解释完成了。

    2 理解参数axis取值对sum结果的影响:

    前面说了axis的取值(以数组a为例),axis=0,1,2。在这里,精确定位到某个元素可以用a[n0][n1][n2]表示。n0的取值是0,1(数组两维),代表第一个索引;n1的取值是0,1,2(每一维数组拥有3个子数组),代表第二个索引;n2的取值是0,1,2,3(每个子数组有4个元素),代表第三个索引,这几个取值在后面会用到。

    2.1 axis = 0的时候:

    axis=0,对应n0已经确定下来,即n0取值定为0,1。所以sum每个元素的求和公式是sum = a[0][n1][n2]+a[1][n1][n2]。接下来确定sum的行数和列数,n1的取值是0,1,2,为3个数,代表行数,n2的取值是0,1,2,3,为4个数,代表列数,所以sum为3*4的数组。

    如何求sum的各个元素呢,sum = a[0][n1][n2]+a[1][n1][n2]这个公式又如何理解呢?如下。我们可以做一个表格:注意颜色

    n2=0               n2=1                n2=2                  n2=3n1=0 a[0][0][0]+a[1][0][0]=1+1=2 a[0][0][1]+a[1][0][1]=2+0=2 a[0][0][2]+a[1][0][2]=3+2=5 a[0][0][3]+a[1][0][3]=2+0=2n1=1 a[0][1][0]+a[1][1][0]=1+2=3 a[0][1][1]+a[1][1][1]=2+1=3 a[0][1][2]+a[1][1][2]=3+2=5 a[0][1][3]+a[1][1][3]=1+0=1n1=2 a[0][2][0]+a[1][2][0]=2+2=4 a[0][2][1]+a[1][2][1]=3+1=4 a[0][2][2]+a[1][2][2]=4+1=5 a[0][2][3]+a[1][2][3]=1+1=2

    所以sum(axis=0)的值是 [ [2, 2, 5, 2], [3, 3, 5, 1], [4, 4, 5, 2]]。

    验证一下, 正确!

    >>> a.sum(axis=0)

    array([[2, 2, 5, 2],

    [3, 3, 5, 1],

    [4, 4, 5, 2]])

    2.2 axis = 1的时候:

    axis=1,对应n1已经确定下来,即n1取值定为0,1,2。所以sum每个元素的求和公式是sum =a[n0][0][n2]+a[n0][1][n2]+a[n0][2][n2]。接下来确定sum的行数和列数,n0的取值是0,1,为2个数,代表行数,n2的取值是0,1,2,3,为4个数,代表列数,所以sum为2*4的数组。

    如何求sum的各个元素呢,sum = a[n0][0][n2]+a[n0][1][n2]+a[n0][2][n2]这个公式又如何理解呢?我们又做一个表格,颜色不标注了

    n2=0n2=1n2=2n2=3n0=0a[0][0][0]+ a[0][1][0]+ a[0][2][0] = 1+1+2=4a[0][0][1]+ a[0][1][1]+ a[0][2][1] =2+2+3=7a[0][0][2]+ a[0][1][2]+ a[0][2][2] =3+3+4=10a[0][0][3]+ a[0][1][3]+ a[0][2][3] =2+1+1=4n0=1a[1][0][0]+ a[1][1][0]+ a[1][2][0] =1+2+2=5a[1][0][1]+ a[1][1][1]+ a[1][2][1] =0+1+1=2a[0][0][2]+ a[0][1][2]+ a[0][2][2] =2+2+1=5a[1][0][3]+ a[1][1][3]+ a[1][2][3] =0+0+1=1

    所以sum(axis=1)的值是 [ [4, 7, 10, 4], [5, 2, 5, 1]]. 验证如下,正确。

    >>> a.sum(axis=1)

    array([[ 4,  7, 10,  4],

    [ 5,  2,  5,  1]])

    2.3 axis = 2的时候:

    axis=2,对应n2已经确定下来,即n2取值定为0,1,2, 3。所以sum每个元素的求和公式是sum =a[n0][n1][0]+a[n0][n1][1]+a[n0][n1][2]+a[n0][n1][3]。接下来确定sum的行数和列数,n0的取值是0,1,为2个数,代表行数,n1的取值是0,1,2,为3个数,代表列数,所以sum为2*3的数组。

    如何求sum的各个元素呢,sum = a[n0][n1][0]+a[n0][n1][1]+a[n0][n1][2]+a[n0][n1][3]这个公式又如何理解呢?我们又做一个表格,颜色不标注了

    n1=0n1=1n1=2n0=0a[0][0][0]+ a[0][0][1]+ a[0][0][2]+ a[0][0][3] =1+2+3+2=8a[0][1][0]+ a[0][1][1]+ a[0][1][2]+ a[0][1][3] =1+2+3+1=7a[0][2][0]+ a[0][2][1]+ a[0][2][2]+ a[0][2][3] =2+3+4+1=10n0=1a[1][0][0]+ a[1][0][1]+ a[1][0][2]+ a[1][0][3] =1+0+2+0=3a[1][1][0]+ a[1][1][1]+ a[1][1][2]+ a[1][1][3] =2+1+2+0=5a[1][2][0]+ a[1][2][1]+ a[1][2][2]+ a[1][2][3] =2+1+1+1=5

    所以sum(axis=2)的值是 [ [8, 7, 10], [3, 5, 5]]. 验证如下,正确。

    >>> a.sum(axis=2)

    array([[ 8,  7, 10],

    [ 3,  5,  5]])

    好了,sum的函数解释结束。

    更多相关内容
  • SUM函数

    千次阅读 2021-07-27 05:15:21
    [编辑]什么是SUM函数SUM函数是求和函数,它是excel函数中最为常用的函数之一,SUM函数分别出现在数学函数、全部函数两个类别中,默认的“常用函数”中也有。主要功能:计算所有参数数值的和;使用格式:SUM(Number1,...

    [编辑]

    什么是SUM函数

    SUM函数是求和函数,它是excel函数中最为常用的函数之一,SUM函数分别出现在数学函数、全部函数两个类别中,默认的“常用函数”中也有。

    主要功能:计算所有参数数值的和;

    使用格式:SUM(Number1,Number2,…)

    参数说明:Number1,Number2,…代表需要计算的值,可以是具体的数值、引用的单元格(区域)、逻辑值等;

    当对某一行或某一列的连续数据进行求和时,还可以使用工具栏中的自动求和按钮“∑”。

    [编辑]

    SUM函数的注意事项

    1、函数的语法中number1,number2等参数,最多有30个;

    2、函数的语法中number1,number2等参数,既可以是数字,也可以是逻辑值,也可以是表达式,也可以是单元格名称,也可以是连续单元格的集合,也可以是单元格区域名称,并且以上所列类别将会被计算;

    3、如果number1等参数为单元格名称、连续单元格集合、单元格区域名称则只计算其中的数值和函数公式数值结果部分,不计算逻辑值、表格中的文字表达式。

    [编辑]

    SUM函数的用法

    [编辑]

    SUM函数的一般性用法

    在SUM函数的一般性用法中可分为两种情况,一是对单元格引用的求和,二是对非单元格引用的求和。

    (一)SUM函数对单元格引用的求和。在对单元格引用求和时单元格中的数据可以有多种类型,数据类型不同SUM函数的结果也将不同。

    1.对数值单元格求和,如Sum(A1,B1)的结果为8;

    2.对逻辑值单元格求和,如Sum(A2,82)的结果为0;

    3.对文本字符单元格求和,如Sum(A3,B3)的结果为0;

    4.对数字字符单元格求和,如Sum(A4,B4)的结果为O。

    从上可以看出SUM函数对单元格引用求和时只有当单元格中的数据是数值时才能计算出我们所期望的值,而其他类型如字符型数据、逻辑型数据或者数字字符都算作O。需要注意的是如果参数是一个数组或引用,则只计算其中的数字。数组或引用中的空白单元格、逻辑值或文本将被忽略。如:SUM({1,2,3},1)=7,而SUM({TRUE,1},1)=2,这是因为TRUE在这里是常量数组而非独立参数,被忽略掉了。

    (二)SUM函数对非单元格引用的求和。所谓非单元格引用的求和,是指在SUM函数格式中直接输入数据值,而不使用单元格地址。在对非单元格引用求和时输入的数据也有多种类型,数据类型不同其结果也有很大的不同。在EXCEL中,针对非单元格引用的求和分下列几种情况:

    1.参数为数值,则直接按数字求和,如Sum(3,5,7)结果为15;

    2.参数为数字字符,自动转换为数值求和,如Sum("3","5","7")结果也为15;

    3.参数为逻辑值,则TRUE返回1,FALSE返回0,如Sum(2,TRUE,FALSE)结果为3;

    4.参数为非数字字符则不能识别,如SUM("计算机",2)返回#VALUE!的错误。

    所以在使用SUM函数求和的时候,不仅要注意单元格引用和非单元格引用的问题,还要注意各种数据类型在这两种情况下,返回的值是不一样的。

    [编辑]

    SUM函数的其他用法

    (一)对交叉区域求和。设A1:E7区域各单元格都有数值,Sum(A4:D7,C2:E5)可以对A4:D7和C2:E5两个区域的求和。如果将括号中的逗号改成空格,则变成了对A4:D7和C2:E5这两个区域的交叉区域C4:D5进行求和,结果就不一样了。如下两图的对比。

    b9defd472fa62fdb85ec695fb6f88705.png

    27f041bd31b5ac246440f07b056b16b2.png

    (二)求累加和。SUM函数结合公式的绝对引用,还可以对一列或一行数掘进行累积求和。设A1到C1分别为列标题"日期"、"日产量"和"累积产量",A、B两列均有着若干行数据,要从C2开始计算各行的累积产量,则可以在单元格C2中输入“=Sum(B$2:B2)”,按住填充柄向下拖拉鼠标至结束即可求出累积产量。

    (三)计数。SUM函数除了可以求和以外还可以用来计数

    除此以外,SUM函数还经常用于一组数据与另一组数据分别相乘再求和汇总。通过以上例子可以看出SUM函数的功能非常强大,除了一般的求和计算外还可以对交叉区域求和或者求累加和。与数组公式结合进行统计计数或者替代Sumif函数进行条件求和。

    [编辑]

    SUM函数的案例分析

    [编辑]

    案例一:

    1.一般应用举例7561a308140da9e2816bbf8b5f5a3752.png

    在图1的成绩表中,要求出每个人的总分和每门课的总分,可以在对应的单元格输入函数:

    图1成绩表

    (1)求每个人的总分:将光标定位到I3单元格,输入函数"=SUM(C3:H3)",然后利用自动填充的方法将公式复制到I4到I54。

    (2)求每门课的总分:将光标定位到C56单元格,输入函数"=SUM(C3:C54)",然后利用自动填充的方法将公式复制到D56到H56。

    注意:如果参数为数组或引用,只有其中的数字将被计算。 数组或引用中的空白单元格、逻辑值、文本或错误值将被忽略。

    2.特殊应用举例

    例1:在图1的成绩表中求每门课程的前3名成绩的和,结果分别放在C57、D57、E57、F57、G57、H57。

    在C57单元格输入"=SUM(LARGE(C3:C54,{1,2,3}))",然后自动填充,则可以求出每门课的前3名成绩的和。

    如果将上面的公式中的LARGE改为SMALL,可以求出后3名的成绩和。

    我们知道SUM函数通常是用来求和的,其实,它也可以用来进行多条件计数,下面的例子说明用它来统计"SQL Server 2000"课程各分数段的学生数。

    例2:在图1的成绩表中统计出课程SQL Server 2000的各分数段的学生人数。

    选中C71单元格,输入公式"=SUM(($F$3:$F$62>=0)*($F$3:$F$62<60))",输入完成后,按下"CTRL+SHIFT+ENTER"组合键进行确认,统计出成绩在0-59区间的学生人数。

    在C72单元格中输入公式"=SUM(($F$3:$F$62>=60)*($F$3:$F$62<70))",输入完成后,按下"CTRL+SHIFT+ENTER"组合键进行确认,可以统计出成绩在60-69分之间的学生人数。

    利用同样的方法可以统计出SQL Server 2000在70-79、80-89、90-100分的人数和其他课程的各分数段的学生人数,结果参看图1。

    [编辑]

    参考文献

    ↑ 周威.Excel中Sum函数的几种用法[J].计算机光盘软件与应用,2011,(第9期).

    本条目对我有帮助3

    MBA智库APP

    扫一扫,下载MBA智库APP

    分享到:

    展开全文
  • Prefix Sum 总结

    千次阅读 2020-03-23 14:41:54
    Interval Sum Given an integer array (index from 0 to n-1, where n is the size of this array), and an query list. Each query has two integers[start, end]. For each query, calculate the sum number bet....

    注意:prefixsum一般都是用PrefixSum[n+1]的数组,prefix[0] = 0; 那么

    因为i, j 是A里面的坐标,而prefixsum比A多了1;所以原来的sum[j] - sum[i-1]变成了

    sum(i~j) = prefixsum(j + 1) - prefixsum(i);

    Interval Sum 思路:因为这个题目不需要modify数组操作,所以用prefix sum array就可以解决,O(N + M) N是数组大小,M是query次数;

    /**
     * Definition of Interval:
     * public classs Interval {
     *     int start, end;
     *     Interval(int start, int end) {
     *         this.start = start;
     *         this.end = end;
     *     }
     * }
     */
    
    public class Solution {
        /**
         * @param A: An integer list
         * @param queries: An query list
         * @return: The result list
         */
        public List<Long> intervalSum(int[] A, List<Interval> queries) {
            List<Long> list = new ArrayList<>();
            int n = A.length;
            long[] prefixsum = new long[n + 1];
            prefixsum[0] = 0;
            for(int i = 1; i <= n; i++) {
                prefixsum[i] = prefixsum[i - 1] + A[i - 1];
            }
            
            for(Interval interval: queries) {
                list.add(prefixsum[interval.end + 1] - prefixsum[interval.start]);
            }
            return list;
        }
    }

     Subarray Sum 用prefixsum, A[i ~ j] = 0; 相当于 S[i-1] == S[j],也就是在数组里面找相等的数;hashmap, 存 S[i], i 就可以了;一定要存index;注意用hashmap put(0,0)因为是为了如果有sum直接== 0, 那么length应该是i - 0 = i;

    public class Solution {
        /**
         * @param nums: A list of integers
         * @return: A list of integers includes the index of the first number and the index of the last number
         */
        public List<Integer> subarraySum(int[] nums) {
            List<Integer> res = new ArrayList<>();
            if(nums == null || nums.length == 0) {
                return res;
            }
            int n = nums.length;
            int[] prefixSum = new int[n + 1];
            prefixSum[0] = 0;
            for(int i = 1; i <= n; i++) {
                prefixSum[i] = prefixSum[i - 1] + nums[i - 1];
            }
    
            HashMap<Integer, Integer> hashmap = new HashMap<>();
            hashmap.put(0, 0);
    
            for(int i = 1; i <= n; i++) {
                if(hashmap.containsKey(prefixSum[i])) {
                    // -1:prefixsum的index都要-1,才能map到原来的array index上;
                    // +1:A[i...j] == 0 -> sum[j] == sum[i - 1]; 求i, 所以要+1;
                    res.add(hashmap.get(prefixSum[i] - 1 + 1));
                    res.add(i - 1);
                }
                hashmap.put(prefixSum[i], i);
            }
            return res;
        }
    }

    Subarray Sum II

    思路:固定右边界aj, 问题转换为找左边的两个边界,

    XXXVVVVVVVVXXXXX aj

    .....ai .................ak ........ aj

         <=end        >=start 

    这两个区间都是可以用双指针来计算得到的,O(N)

    Prefix Sum 现在用n+1数组来求;

    public class Solution {
        /**
         * @param A: An integer array
         * @param start: An integer
         * @param end: An integer
         * @return: the number of possible answer
         */
        public int subarraySumII(int[] A, int start, int end) {
            if(A == null || A.length == 0) {
                return 0;
            }
            int n = A.length;
            int[] prefixSum = new int[n + 1];
            prefixSum[0] = 0;
            for(int i = 1; i <= n; i++) {
                prefixSum[i] = prefixSum[i - 1] + A[i - 1];
            }
    
            int res = 0;
            /**
            XXXXXXVVVVVVVVVXXXXXX j
              >end         <start
              left          right
            */
            int left = 0, right = 0;
            for(int j = 1; j <= n; j++) {
                while(right < j && prefixSum[j] - prefixSum[right] >= start) {
                    right++;
                }
                while(left < j && prefixSum[j] - prefixSum[left] > end) {
                    left++;
                }
                res += (right - left);
            }
            return res;
        }
    }

    Subarray Sum Closest 思路:将prefixsum的array,排序,然后比较相邻的两个sum,如果求diff最小的,注意;如果prefixsum == 0,则不用找了,找了个最佳答案,否则看最相近的;

    public class Solution {
        /*
         * @param nums: A list of integers
         * @return: A list of integers includes the index of the first number and the index of the last number
         */
        private class Node {
            public int index;
            public int sum;
            public Node(int index, int sum) {
                this.index = index;
                this.sum = sum;
            }
        }
        
        public int[] subarraySumClosest(int[] nums) {
            int[] res = new int[2];
            if(nums == null || nums.length == 0) {
                return res;
            }
            int n = nums.length;
            int[] sum = new int[n + 1];
            sum[0] = 0;
            List<Node> list = new ArrayList<Node>();
            for(int i = 1; i <= n; i++) {
                sum[i] = sum[i - 1] + nums[i - 1];
                if(sum[i] == 0) {
                    res[0] = 0;
                    res[1] = i - 1;
                    return res;
                }
                list.add(new Node(i, sum[i]));
            }
            Collections.sort(list, (a, b) ->(a.sum - b.sum));
            
            int diff = Integer.MAX_VALUE;
            for(int i = 0; i < list.size() - 1; i++) {
                int curdiff = list.get(i + 1).sum - list.get(i).sum;
                if(curdiff < diff) {
                    diff = curdiff;
                    // sum[i, j] = S[j] - S[i - 1], 所以真正的区间是: [i + 1, j]
                    if(list.get(i).index < list.get(i + 1).index) {
                        res[0] = list.get(i).index;
                        res[1] = list.get(i + 1).index - 1;
                    } else {
                        res[0] = list.get(i + 1).index;
                        res[1] = list.get(i).index - 1;
                    }
                }
            }
            return res;
        }
    }

    Submatrix Sum 用prefixsum,代表是从(0,0) 到(i,j) 的区域sum。然后固定上边界和下边界,然后扫描j,用hashmap来找有没有重复的区域,如果有就找到了区域为0的,然后记录答案,注意,因为prefixsum是+1了的index,所以,最后右下角的点需要减去1,左上角的点因为默认+1,所以不用减去1了。 O(N^3); Space O(N^2);

    public class Solution {
        /*
         * @param matrix: an integer matrix
         * @return: the coordinate of the left-up and right-down number
         */
        public int[][] submatrixSum(int[][] matrix) {
            int[][] res = new int[2][2];
            if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
                return res;
            }
            int m = matrix.length;
            int n = matrix[0].length;
    
            int[][] prefixSum = new int[m + 1][n + 1];
            for(int i = 0; i <= m; i++) {
                for(int j = 0; j <= n; j++) {
                    if(i == 0 || j == 0) {
                        prefixSum[i][j] = 0;
                    } else {
                        prefixSum[i][j] = prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1] + matrix[i - 1][j - 1];
                    }
                }
            }
            
            for(int x1 = 0; x1 < m; x1++) {
                for(int x2 = x1 + 1; x2 <= m; x2++) {
                    // 记住,这里每次循环都要新建一个hashmap;
                    HashMap<Integer, Integer> hashmap = new HashMap<>();
                    for(int j = 0; j <= n; j++) {
                        int area = prefixSum[x2][j] - prefixSum[x1][j];
                        if(hashmap.containsKey(area)) {
                            int k = hashmap.get(area);
                            res[0][0] = x1;
                            res[0][1] = k;
                            res[1][0] = x2 - 1;
                            res[1][1] = j - 1;
                        } else {
                            hashmap.put(area, j);
                        }
                    }
                }
            }
            return res;
        }
    }

    Lintcode: Continuous Subarray Sum 思路:

    思路:用prefixsum来做,求最大,那么就跟股票那题一样,存一个最小,然后每次跟最小比差,如果大,记录下来。注意prefixsum的index默认是+1了的,所以result是[start, i - 1];

    是因为sum[i, j] = S[j] - S[i - 1], = prefixsum[j + 1] - prefixsum[i], prefixsum里面的index是原来数组的index + 1所形成。所以在prefixsum的index要还原成原来array的index都要减去1,然而,S[j] - S[i - 1] == Sum[i,j],所以求i的范围,需要把start +1,这样start + 1 - 1=start, end - 1,就是对应原来数组的index了;

    public class Solution {
        /*
         * @param A: An integer array
         * @return: A list of integers includes the index of the first number and the index of the last number
         */
        public List<Integer> continuousSubarraySum(int[] A) {
            List<Integer> list = new ArrayList<Integer>();
            if(A == null || A.length == 0) {
                return list;
            }
            int sum = 0;
            int minsum = 0;
            int max = Integer.MIN_VALUE;
            int start = 0, end = 0;
            list.add(start); 
            list.add(end);
            int n = A.length;
            for(int i = 1; i <= n; i++) {
                sum += A[i - 1];
                if(sum - minsum > max) {
                    max = sum - minsum;
                    list.set(0, start);
                    list.set(1, i - 1);
                }
                if(sum < minsum) {
                    minsum = sum;
                    start = i;
                }
            }
            return list;
        }
    }

    [LeetCode Continuous Subarray Sum] 思路:这题算法是根据(a + n*k) % k == a % k, 所以 [23,2,6,4,7] k = 6, the running sum is [23,25,31,35,42] and the remainders are [5,1,1,5,0]. We got remainder 5 at index 0 and at index 3. That means, in between these two indexes we must have added a number which is multiple of the k.  也就是跟two sum类似,如果存 ( cursum % k )余数和index,那么如果我又遇见了同样的余数,那么代表中间肯定有个subarray 和是n * k. 注意这题tricky的地方是: [0,0] 0 或者[6,6] 6 这种,如果map.put(0,0)会返回false,处理的方法就是map.put(0,-1)这样代表余数是0的情况可以有1 个,我遇见的下一个,肯定可以判断是len > 1 从而返回true

    class Solution {
        public boolean checkSubarraySum(int[] nums, int k) {
            if(nums == null || nums.length == 0) {
                return false;
            }
            HashMap<Integer, Integer> hashmap = new HashMap<>();
            // value = -1 is due to the fact that the size of the subarray is required to be least two
            // 因为key 是sum,value是index,题目要求array at least 2.所以,如果找到一个sum,另外一个index 减去current index,就必须 > 1; 所以存-1;
            hashmap.put(0, -1); 
            int cursum = 0;
            for(int i = 0; i < nums.length; i++) {
                cursum += nums[i];
                if(k != 0) {
                    cursum = cursum % k;
                }
                Integer pre = hashmap.get(cursum);
                if(pre != null) {
                    if(i - pre > 1) {
                        return true;
                    }
                } else {
                    hashmap.put(cursum, i);
                }
            }
            return false;
        }
    }

    Range Sum Query - Immutable Prefix 模板,Sum[i, j] = prefixsum[j + 1] - prefixsum[i]; 

    class NumArray {
        private int[] prefixsum;
        public NumArray(int[] nums) {
            int n = nums.length;
            this.prefixsum = new int[n + 1];
            for(int i = 1; i <= n; i++) {
                prefixsum[i] = prefixsum[i - 1] + nums[i - 1];
            }
        }
        
        public int sumRange(int i, int j) {
            return prefixsum[j + 1] - prefixsum[i];
        }
    }
    
    /**
     * Your NumArray object will be instantiated and called as such:
     * NumArray obj = new NumArray(nums);
     * int param_1 = obj.sumRange(i,j);
     */

    Subarray Sum Equals K 思路:用prefixsum prefixsum[j+1] - prefixsum[i] = k,  O(N^2) 优化就是:类似2sum,用hashmap优化,注意先判断是否含有,再加入,否则会有重复计算;O(N) Space O(N);

    class Solution {
        public int subarraySum(int[] nums, int k) {
            if(nums == null || nums.length == 0) {
                return 0;
            }
            int n = nums.length;
            int cursum = 0;
            
            //       sum      frequency;
            HashMap<Integer, Integer> hashmap = new HashMap<>();
           
            int count = 0;
            for(int i = 0; i < nums.length; i++) {
                cursum += nums[i];
                if(cursum == k) {
                    count++;
                }
                // 存prefixsum - k, 也就是之前的比较小的数,这样在后面一旦碰见,那么就表示相吻合,a - b = k;
                // count已经加过1了,那么这里只需要加入之前的频率。
                if(hashmap.containsKey(cursum - k)) {
                    count += hashmap.get(cursum - k);
                }
                // hashmap里面的频率要+1;
                hashmap.put(cursum, hashmap.getOrDefault(cursum, 0) + 1);
            }
            return count;
        }
    }

    Number of Submatrices That Sum to Target   这类矩阵的题目,就矩阵和,都是prefixsum的思路,这里比较巧妙的是,用每一行的prefixsum来求解,i, j 是start col, end col, k是row,相当于从右往左投影计算array[k], 把j往左投影,然后array 其实是一个竖着的矩阵往左投影sum的结果。问题就变成了560. Subarray Sum Equals K , 注意hashmap每次都要重新生成,因为i, j  变化了,那么相当于每次生成一个新的array了,所以每次都是一次新的计算; Time : O(col ^2 * row);

    class Solution {
        public int numSubmatrixSumTarget(int[][] matrix, int target) {
            int n = matrix.length;
            int m = matrix[0].length;
            int[] array = new int[n];
            
            int res = 0;
            for(int i = 0; i < m; i++) {
                Arrays.fill(array, 0);
                for(int j = i; j < m; j++) {
                    for(int k = 0; k < n; k++) { // j每次增加一格,k从上到下,都要加入对应的array[k];
                        array[k] += matrix[k][j]; // 把每一行k, [i,j] sum起来;
                    }
                    res += subarraySum(array, target);
                }   
            }
            return res;
        }
        
         public int subarraySum(int[] nums, int k) {
            if(nums == null || nums.length == 0) {
                return 0;
            }
            HashMap<Integer, Integer> hashmap = new HashMap<>();
            int sum = 0;
            int count = 0;
            for(int i = 0; i < nums.length; i++) {
                sum += nums[i];
                if(sum == k) {
                    count++;
                }
                if(hashmap.containsKey(sum - k)) {
                    count += hashmap.get(sum - k);
                }
                hashmap.put(sum, hashmap.getOrDefault(sum, 0) + 1);
            }
            return count;
        }
    }

    Find Pivot Index 思路:prefixsum的模板,注意index可以是最后一个,因为整个array sum == 0,也是可以的;

    class Solution {
        public int pivotIndex(int[] nums) {
            if(nums == null || nums.length == 0) {
                return -1;
            }
            int n = nums.length;
            int[] prefixsum = new int[n + 1];
            prefixsum[0] = 0;
            for(int i = 1; i <= n; i++) {
                prefixsum[i] = prefixsum[i - 1] + nums[i - 1];
            }
            
            for(int i = 1; i <= n; i++) {
                int leftsum = prefixsum[i - 1];
                int rightsum = prefixsum[n] - prefixsum[i];
                if(leftsum == rightsum) {
                    return i - 1;
                }
            }
            return -1;
        }
    }

    Split Array with Equal Sum 思路:先固定j,然后左边分两半,sum相等就存入hashset,然后右边分两半,sum相等,就看sum在不在hashset里面;这里presum用0开始的index,这样写prefixsum好写。严格按照// 0 < i, i + 1 < j, j + 1 < k < n - 1; 这个提示来写。

    class Solution {
        public boolean splitArray(int[] nums) {
            if(nums == null || nums.length == 0) {
                return false;
            }
            int n = nums.length;
            int[] prefixsum = new int[n];
            prefixsum[0] = nums[0];
            for(int i = 1; i < n; i++) {
                prefixsum[i] = prefixsum[i - 1] + nums[i];
            }
            
            // 0 < i, i + 1 < j, j + 1 < k < n - 1
            for(int j = 3; j < n - 3; j++) {
                HashSet<Integer> set = new HashSet<>();
                for(int i = 1; i + 1 < j; i++) {
                    if(prefixsum[i - 1] == prefixsum[j - 1] - prefixsum[i]) {
                        set.add(prefixsum[i - 1]);
                    }
                }
                
                for(int k = j + 2; k < n - 1; k++) {
                    if(prefixsum[k - 1] - prefixsum[j] == prefixsum[n - 1] - prefixsum[k]) {
                        if(set.contains(prefixsum[n - 1] - prefixsum[k])) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    }

    Product of the Last K Numbers  思路:prefix product array,注意默认的第一位是个1,然后往后面加 list.get( list.size() - 1) * num;最后,k == n的时候,因为前面有1,所以return 0,超过了输入num的个数范围;

    class ProductOfNumbers {
    
        private ArrayList<Integer> list;
        public ProductOfNumbers() {
            list = new ArrayList();
            list.add(1); // 跟prefix一样,第一个元素add为1;
        }
        
        public void add(int num) {
            if(num == 0) {
                list.clear();
                list.add(1);
            } else {
                list.add(list.get(list.size() - 1) * num);
            }
        }
        
        public int getProduct(int k) {
            int n = list.size();
            //因为前面加了默认1,跟prefixsum一样,所以k == n 相当于k 大于了元素个数了,直接return 0;
            if(k >= n) { 
                return 0;
            } else {
                return list.get(n - 1) / list.get(n - 1 - k);
            }
        }
    }
    
    /**
     * Your ProductOfNumbers object will be instantiated and called as such:
     * ProductOfNumbers obj = new ProductOfNumbers();
     * obj.add(num);
     * int param_2 = obj.getProduct(k);
     */

    Find Two Non-overlapping Sub-arrays Each With Target Sum 这题很类似于560. Subarray Sum Equals K, 不同在于要找两个不同的subarray,那么如何找两个array就是利用dp[i]来找,dp[i]存的物理意义是,到目前subarry sum为target的最小的length,如果pre != -1 && dp[pre] != Integer.MAX_VALUE代表找到了第二array,之前还有一个array和为target;因为dp[i] = dp[i - 1];所以只有一个的话,dp[pre]会一直是integer.MAX_VALUE;

    注意:计算prefixsum的index,必须加入-1,因为前几个数和就是target,如果要算length,就是i - (-1) = i + 1;因为i是0开头的;560. Subarray Sum Equals K 那个题是用hashmap存prefixsum , frequency. 计算频率,就(0,1)如果计算index或者长度就是(0,-1)。

    class Solution {
        public int minSumOfLengths(int[] arr, int target) {
            if(arr == null || arr.length == 0) {
                return -1;
            }
            HashMap<Integer, Integer> hashmap = new HashMap<>();
            // 计算prefixsum的index,必须加入-1,因为前几个数和就是target,如果要算length,就是i - (-1) = i + 1;因为i是0开头的;
            hashmap.put(0, -1);
            int n = arr.length;
            int[] dp = new int[n];
            int res = Integer.MAX_VALUE;
            int cursum = 0;
            for(int i = 0; i < arr.length; i++) {
                cursum += arr[i];
                dp[i] = i > 0 ? dp[i - 1] : Integer.MAX_VALUE;
                
                if(hashmap.containsKey(cursum - target)) {
                    int pre = hashmap.get(cursum - target);
                    dp[i] = Math.min(dp[i], i - pre);
                    
                    // 如何求得两个区间,就是用dp[i] 记录到目前为止,cursum == target的array的最小的length;
                    // 如果 pre == -1 或者dp[pre] == Integer.MAX_VALUE,代表之前只找到一个区间;如果不是,那么就是之前已经找到一个区间,现在找到了第二个区间;
                    if(pre != -1 && dp[pre] != Integer.MAX_VALUE) {
                        res = Math.min(res, dp[pre] + i - pre);
                    }
                }
                hashmap.put(cursum, i);
            }
            return res == Integer.MAX_VALUE ? -1 : res;
        }
    }

    Max Sum of Rectangle No Larger Than K 核心思想就是:每列column,从左向右投影,left, right, 是左右边界,然后sums[n] 是长度为row的投影sum,也就是prefixsum。每次移动left, right,计算出sums array之后,问题就转换为,在一个array里面,找subarray sum最接近K的sum;这里用了treeset ceiling是第一个大于input的value,num >= currsum - k; currsum - num <= k; 每次update这个currsum - num  就可以了。currsum 是累加的sum;

    注意:currusm - num 代表的就是下面的block的matrix;set.add(0); // 需要padding,是为了解决只有一个row value的情况;比如说cursum = 10, k = 10,那么就只有一个sum的话,就是要返回10,如果没有0,就会返回null,得不到sum就等于k的情况;

    class Solution {
        public int maxSumSubmatrix(int[][] matrix, int k) {
            if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
                return 0;
            }
            
            int n = matrix.length;
            int m = matrix[0].length;
            int result = Integer.MIN_VALUE;
            
            for(int left = 0; left < m; left++) {
                int[] arr = new int[n];
                for(int right = left; right < m; right++) {
                    for(int i = 0; i < n; i++) {
                        arr[i] += matrix[i][right];
                    }
                    
                    TreeSet<Integer> treeset = new TreeSet<>();
                    // 需要padding,是为了解决只有一个row value的情况;
                    // 比如说cursum = 10, k = 10,那么就只有一个sum的话,就是要返回10,如果没有0,就会返回null,得不到sum就等于k的情况;
                    treeset.add(0);
                    int cursum = 0;
                    
                    for(int prefixsum: arr) {
                        cursum += prefixsum;
                        // num >= cursum - k;
                        // k >= cursum - num;
                        Integer num = treeset.ceiling(cursum - k);
                        if(num != null) {
                            // k >= cursum - num;
                            // currusm - num 代表的就是下面的block的matrix;
                            result = Math.max(result, cursum - num);
                        }
                        treeset.add(cursum);
                    }
                }
            }
            return result;
        }
    }

    Shortest Subarray with Sum at Least K  思路:这题跟Minimum Size Subarray Sum 很相似,不同的是,加入了负数,使得问题变复杂了。思路就是:求区间和,很容易想到prefixsum,这个很好求出,但是怎么扫描去求sum>=k的最小区间长度,sum[i] .... sum[j].... sum[k] 如果sum[i] > sum[j], sum[k] - sum[i] >=k, 那么sum[k] - sum[j] 更加>=k,同时j > i,那么j到k区间会更小,那么sum[i]就没必要存,发现这个性质那么就是单调栈,前面的数sum[i], 比当前的数sum[j]要大,就没必要存,那么栈里面就是单调递增的,我们要保持里面是递增的,那么后面进来的数,如果比last要小,则踢掉前面的数,为什么?是因为如果存了,last > i, future - last >= k, 那么future - i 更加>= k, 所以 last比i大,没必要存;

    More detailed on this, we always add at the LAST position
    B[d.back] <- B[i] <- ... <- B[future id]
    B[future id] - B[d.back()] >= k && B[d.back()] >= B[i]
    B[future id] - B[i] >= k too

    前后都要进出,那么用deque可以满足要求。这里要注意一点,长度是 i - deque.peekFirst()。为什么,是因为sum[j] - sum[i] ,subarray的长度其实是i + 1,...j,那么就是j - i + 1 - 1 = j - i;

    class Solution {
        public int shortestSubarray(int[] A, int K) {
            if(A == null || A.length == 0) {
                return -1;
            }
            int n = A.length;
            int[] prefixsum = new int[n + 1];
            prefixsum[0] = 0;
            for(int i = 1; i <= n; i++) {
                prefixsum[i] = prefixsum[i - 1] + A[i - 1];
            }
            Deque<Integer> arrayDeque = new ArrayDeque<Integer>();
            int res = Integer.MAX_VALUE;
            for(int i = 0; i <= n; i++) {
                while(!arrayDeque.isEmpty() && prefixsum[i] - prefixsum[arrayDeque.peekFirst()] >= K) {
                    res = Math.min(res, i - arrayDeque.peekFirst());
                    arrayDeque.pollFirst();
                }
                while(!arrayDeque.isEmpty() && prefixsum[i] <= prefixsum[arrayDeque.peekLast()]) {
                    arrayDeque.pollLast();
                }
                arrayDeque.offer(i);
            }
            return res == Integer.MAX_VALUE ? -1 : res;
        }
    }

    Maximum Side Length of a Square with Sum Less than or Equal to Threshold  思路:build 矩阵的prefixsum ,记住建立的时候是 sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + mat[i - 1][j - 1];

    利用prefixsum求正方形的时候是:sum[i][j] - sum[i - len][j] - sum[i][j - len] + sum[i - len][j - len]

    建立好prefixsum之后,在0,math.min(n,m)之间做binary search, T: n * m * log(min(n,m));

    生成prefixsum的时候,是从上到下生成,计算区间的时候,是相减的;不要记忆公式,逻辑推理就行;

    class Solution {
        public int maxSideLength(int[][] mat, int threshold) {
            int n = mat.length;
            int m = mat[0].length;
            int[][] sum = new int[n + 1][m + 1];
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= m; j++) {
                    sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + mat[i - 1][j - 1];
                }
            }
            
            int start = 0; int end = Math.min(n, m);
            while(start + 1 < end) {
                int mid = start + (end - start) / 2;
                if(canhave(mat, mid, threshold, sum)) {
                    start = mid;
                } else {
                    end = mid;
                }
            }
            
            if(canhave(mat, end, threshold, sum)) {
                return end;
            }
            if(canhave(mat, start, threshold, sum)) {
                return start;
            }
            return 0;
        }
        
        private boolean canhave(int[][] mat, int len, int threshold, int[][] sum) {
            for(int i = len; i <= mat.length; i++) {
                for(int j = len; j <= mat[0].length; j++) {
                    if(sum[i][j] - sum[i - len][j] - sum[i][j - len] + sum[i - len][j - len] <= threshold) {
                        return true;
                    }
                }
            }
            return false;
        }
    }

    思路2:这个比较巧妙,就是在建立prefixsum 矩阵的时候,一起判断,是否有比len更大的合法正方形,有就len++;O(m * n);

    class Solution {
        public int maxSideLength(int[][] mat, int threshold) {
            if(mat == null || mat.length == 0 || mat[0].length == 0) {
                return 0;
            }
            int n = mat.length;
            int m = mat[0].length;
            int[][] prefixsum = new int[n + 1][m + 1];
            int len = 1;
            int res = 0;
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= m; j++) {
                    prefixsum[i][j] = prefixsum[i - 1][j] + prefixsum[i][j - 1] - prefixsum[i - 1][j - 1] + mat[i - 1][j - 1];
                    if(i - len >= 0 && j - len >= 0
                      && prefixsum[i][j] - prefixsum[i - len][j] - prefixsum[i][j - len] + prefixsum[i - len][j - len] <= threshold) {
                        res = len;
                        len++;
                    }
                }
            }
            return res;
        }
    }

    Maximum Size Subarray Sum Equals k 思路:prefixsum,这里可以不用array存,直接sum加起来,用hashmap就变成了<Integer, Integer> sum, index 只要查sum - target 是否存在就可以,存在就是当前index - i,0...i ...j 长度就是j - i; O(N)

    class Solution {
        public int maxSubArrayLen(int[] nums, int k) {
            if(nums == null || nums.length == 0) {
                return 0;
            }
            int res = 0;
            int cursum = 0;
            //       cursum   0 based index
            HashMap<Integer, Integer> hashmap = new HashMap<>();
            hashmap.put(0, -1); // 是为了array刚好 0...j 元素和是target,那么长度是j - (-1) = j + 1用的;
            for(int i = 0; i < nums.length; i++) {
                cursum += nums[i];
                if(hashmap.containsKey(cursum - k)) {
                    res = Math.max(res, i - hashmap.get(cursum - k));
                }
                // 这行很关键,就是之前有,就不要存,因为是找最大的length,所以前面的不要覆盖掉;
                if(!hashmap.containsKey(cursum)) {
                    hashmap.put(cursum, i);
                }
            }
            return res;
        }
    }

    Matrix Block Sum 思路:这题其实考点就是个prefixSum,Sum[i..j] = PrefixSum[j] - PrefixSum[i-1],注意这里是i - 1;

    // 这个点是i - k + 1的上面一个点,根据prefixSum 定义
    // Sum[i, j] = PrefixSum[j] - PrefixSum[i-1];
    // i - 1,也就是这个点;所以这里r1, c1没有+1;

    r1 c1

                  r2 c2

    r1, c1 的点,其实是区域范围 (i - k + 1, j - k  + 1)的上一个点;

    class Solution {
        public int[][] matrixBlockSum(int[][] mat, int k) {
            if(mat == null || mat.length == 0 || mat[0].length == 0) {
                return mat;
            }
            int m = mat.length;
            int n = mat[0].length;
            int[][] prefixSum = new int[m + 1][n + 1];
            for(int i = 0; i <= m; i++) {
                for(int j = 0; j <= n; j++) {
                    if(i == 0 || j == 0) {
                        prefixSum[i][j] = 0;
                    } else {
                        prefixSum[i][j] = prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1]
                                          + mat[i - 1][j - 1];
                    }
                }
            }
            
            int[][] res = new int[m][n];
            for(int i = 0; i < m; i++) {
                for(int j = 0; j < n; j++) {
                    int r1 = Math.max(0, i - k);
                    int c1 = Math.max(0, j - k);
                    
                    int r2 = Math.min(m, i + k + 1);
                    int c2 = Math.min(n, j + k + 1);
                    
                    res[i][j] = prefixSum[r2][c2] - prefixSum[r1][c2] - prefixSum[r2][c1] + prefixSum[r1][c1];
                }
            }
            return res;
        }
    }

    Maximum Sum of 3 Non-Overlapping Subarrays  思路:这个题目还是比较巧妙的,要求三段的和最大,核心算法就是:固定中间的一段subarry,分别用O(1)的时间去求左边部分的最大的subarry和,右边部分的最大的subarry的和。怎么用O(1)的时间去求subarry,很简单,prefixsum。但是怎么O(1)的去求一个大区间里面,哪一段的subarry是最大的,这个点就要用dp来pre compute,用leftdp记录到目前为止,从左往右看,到第i为止的最大的k size的subarry的起点index,同理:rightdp记录从右往左看 k size最大和的起点;这样有了这两个array,我就可以一口气算出

    [0, i] [i, i + k -1] [i + k, n - 1] 三个区间段里面,哪三段的和最大,左边和右边可以O(1)算出来,中间的i在动,但是也可以O(1)计算出来;

    prefixsum index的推倒,要熟练;

    sum[i, j] = prefixsum[j] - prefixsum[i - 1] 由于 array +1了,所以 prefixsum[j + 1] - prefixsum[i] 

    i 跟j之间有k,那么  j = i + k - 1 <==>  i = j - k + 1;

    从左往右计算,是j在移动,所以消除 i,prefixsum[j + 1] - prefixsum[j - k + 1];

    从右往左计算,是i在移动,所以消除 j,prefixsum[i + k - 1 + 1] - prefixsum[i] = prefixsum[i + k] - prefixsum[i];

    class Solution {
        public int[] maxSumOfThreeSubarrays(int[] nums, int k) {
            int n = nums.length;
            int[] presum = new int[n + 1];
            for(int i = 0; i < n; i++) {
                presum[i + 1] = presum[i] + nums[i];
            }
            
            // 记录到目前i为止的,从左往右看,最大的subarry的和的起始位子;
            int[] leftdp = new int[n];
            // 记录到目前i为止的,从右往左看,最大的subarry的和的起始位子;
            int[] rightdp = new int[n];
            
            leftdp[k] = 0;
            for(int j = k, total = presum[k] - presum[0]; j < n; j++) {
                if(presum[j + 1] - presum[j - k + 1] > total) {
                    total = presum[j + 1] - presum[j - k + 1];
                    leftdp[j] = j - k + 1;
                } else {
                    leftdp[j] = leftdp[j - 1];
                }
            }
            
            rightdp[n - k] = n - k;
            for(int i = n - k - 1, total = presum[n] - presum[n - k]; i >= 0; i--) {
                if(presum[i + k] - presum[i] >= total) {
                    total = presum[i + k] - presum[i];
                    rightdp[i] = i;
                } else {
                    rightdp[i] = rightdp[i + 1];
                }
            }
            
            // left,     middle,        right;
            // [0, i], [i, i + k - 1], [i + k, n - 1];
            int[] res = {-1,-1,-1};
            int maxsum = 0;
            // 左边最起码要有k个,所以start = k,右边也是要有k个,那么起点就是倒数第二个k个,也就是 n - 2*k;
            // 核心算法:就是固定中间的subarry,然后一口气算出各个subarry的和,怎么算,
            // 也就是pre calculate的leftdp, rightdp, 
            // 然后用leftdp 和rightdp O(1)去算各个subarry的和;
            for(int i = k; i <= n - 2 * k; i++) {
                int l = leftdp[i - 1];
                int r = rightdp[i + k];
                int cursum = (presum[l + k] - presum[l]) 
                            + (presum[i + k] - presum[i]) 
                            + (presum[r + k] - presum[r]);
                if(cursum > maxsum) {
                    maxsum = cursum;
                    res[0] = l;
                    res[1] = i;
                    res[2] = r;
                }
            }
            return res;
        }
    }
    展开全文
  • sum(-1)、sum(1)、sum(0)、sum()与axis=-1,1,0

    万次阅读 2021-07-13 10:15:52
    np.sum() 一、axis 一句话解释:设axis=i,则沿着第i个下标变化的方向进行操作(忽略该下标,其他下标相同的为一组,然后再对该组进行操作) axis是将矩阵进行分组,然后再操作。而分组则意味着会降维,则每axis...

    目录

    一、axis

     实例:

    axis=0:

    以axis=-1:

    2. 对axis的理解

    np.sum()


    一、axis

    一句话解释:设axis=i,则沿着第i个下标变化的方向进行操作(忽略该下标,其他下标相同的为一组,然后再对该组进行操作)

    axis是将矩阵进行分组,然后再操作。而分组则意味着会降维,则每axis一次,维度就降低1(例如原来为三维矩阵, 现在对它进行操作,就会变为二维的)

    当numpy函数不指定axis的值时,表示函数对所有元素进行操作;

    当numpy函数指定axis的值时,表示函数沿着指定的axis轴方向进行操作;

    axis=0:可以理解为按照行顺序,对列进行操作

    axis=1:可以理解为按照列顺序,对行进行操作

    >>> import numpy as np
    
    >>> a=np.array([[1,2],
                    [3,4],
                    [5,6]])
    
    >>> a.mean(axis=0)#按照行顺序,对每一列求均值
    array([3., 4.])
    >>> a.mean(axis=1)#按照列顺序,对每一行求均值
    array([1.5, 3.5, 5.5]) 
    

     实例:

    
    import numpy as np
    
    np.random.seed(1234)
    embeddings  = np.random.randint(0, 10, size=[3, 3, 5])
    print(embeddings )
    
    a = np.max(embeddings ,axis=-1)
    b = np.max(embeddings ,axis=0)
    c = np.max(embeddings ,axis=1)
    
    print(a)
    print(b)
    print(c)
    
    

    [[[3 6 5 4 8]
      [9 1 7 9 6]
      [8 0 5 0 9]]

     [[6 2 0 5 2]
      [6 3 7 0 9]
      [0 3 2 3 1]]

     [[3 1 3 7 1]
      [7 4 0 5 1]
      [5 9 9 4 0]]]

    结果为:

    [[8 9 9]
     [6 9 3]
     [7 7 9]]

    [[6 6 5 7 8]
     [9 4 7 9 9]
     [8 9 9 4 9]]

    [[9 6 7 9 9]
     [6 3 7 5 9]
     [7 9 9 7 1]]

    刚刚的矩阵写成下标表示就是:

    embeddings = [[[a000,a001,a002,a003,a004],
                              [a010,a011,a012,a013,a014],
                              [a020,a021,a022,a023,a024],              
                              [a030,a031,a032,a033,a034]]
                  
                             [[a100,a101,a102,a103,a104],
                              [a110,a111,a112,a113,a114],
                              [a120,a121,a122,a123,a124],              
                              [a130,a131,a132,a133,a134]]
                  
                             [[a200,a201,a202,a203,a204],
                              [a210,a211,a212,a213,a214],
                              [a220,a221,a222,a223,a224],              
                              [a230,a231,a232,a233,a234]]       

    axis=0:

    以axis=0为例,则沿着第0个下标(最左边的下标)变化的方向进行操作,也就是将除了第0个下标外,其他两个下标都相同的部分分成一组,然后再进行操作。具体分组如下(省略了一些组):

    从上图可以看出,每3个数分成一组,所以现在总共是分了4*5个组(所以最终返回的结果也是一个shape=[4,5]的矩阵),对每个组都执行一次 max操作,将每个组的三个数中数值最大的数构成矩阵。

    以axis=-1:

    his means that the index that will be returned by argmax will be taken from the last axis.

    这里需要特别说明一下axis=-1的操作,可能对python不熟悉的人会不理解这里的-1是哪个维度。在pyhton中,-1代表倒数第一个,也就是说,假如你的矩阵shape=[3,4,5],那么对这个矩阵来说,axis=-1,其实也就等于axis=2。因为这是个三维矩阵,所以axis可能的取值为0,1,2,所以最后一个就是2。你可以自己试试看两个取值结果是否相同。

    2. 对axis的理解

    通过上面的例子,你可能已经发现了,axis是将矩阵进行分组,然后再操作。而分组则意味着会降维

    以刚刚的例子,原始矩阵的shape=[3,4,5],取axis=0再进行操作后,得到的矩阵shape=[4,5]。同样的,取axis=1再进行操作后,得到的矩阵shape=[3,5]。取axis=-1(axis=2)再操作后,shape=[3,4]。掌握这一点,能有利于你在神经网络中的变换或是数据操作中明确矩阵变换前后的形状,从而加快对模型的理解。

    np.sum()

    函数原型:

    np.sum(a, axis=None, dtype=None, out=None, keepdims=False)

    函数作用:

    求给定的axis轴上的数组元素之和

    import numpy as np
    
    A = np.array([[1,2],
                  [3,4]])
    sum0 = np.sum(A, axis=0)    #沿着0轴求和 ,也就是与0轴平行的方向求和(按列求和)
    sum1 = np.sum(A, axis=1)    #沿着1轴求和,也就是与1轴平行的方向求和(按行求和)
    sum2 = np.sum(A)
    
    print("输入矩阵:")
    print(A)
    
    print("沿着0轴求和(按列,axis = 0):",sum0)
    print("沿着1轴求和(按行,aixs = 1):",sum1)
    print("所有元素的和(axis = none):",sum2)
    

    结果:

    输入矩阵:

    [[1 2] [3 4]]

    沿着0轴求和(按列,axis = 0): [4 6]

    沿着1轴求和(按行,aixs = 1): [3 7]

    所有元素的和(axis = none): 10

    展开全文
  • SQL Sum()函数

    万次阅读 2021-05-06 05:25:57
    在本教程中,我们将演示如何使用SQL SUM函数,此函数计算所有值或不同值的总和。1. SQL SUM函数简介SQL SUM函数是一个聚合函数,它返回所有或不同值的总和。需要注意的是,只能将SUM函数应用于数字列。以下说明了SUM...
  • 解密中国人自己的操作系统DIM-SUM

    千次阅读 2020-07-28 17:30:02
    如果说DIM-SUM操作系统是一个完美的操作系统,那无疑是一个谎言。如果说DIM-SUM操作系统只是大家茶余饭后的谈资,那无疑是另一个谎言。 在国产基础软件大发展的历史背景下,自研国产操作系统显得十分迫切和必要。...
  • 【算法】2SUM/3SUM/4SUM问题

    万次阅读 2017-04-26 01:21:50
    之前就总结过一些Leetcode上各种sum问题,今天再拿出来完整得总结一番。 nSUM问题是指,在一个数组中,找出n个数相加和等于给定的数,这个叫做nSUM问题。 常见的有2SUM,3SUM,4SUM问题,还有各种SUM问题的变种....
  • matlab中的sum(X,2)是什么意思呢

    千次阅读 2021-04-18 07:14:33
    然后把这道题拍照上传到作业帮之中,就能够有详细的解答,其实sum这样用并不是复很制规范,按照某人2113的说法“要是10维数组,5261还要写10个sum不成”。其4102实可以1653这样写的B = sum(abs(x(:)...
  • sql sum语句_SQL Sum语句示例说明

    千次阅读 2020-08-13 15:21:17
    sql sum语句 SQL中的Sum语句是什么? (What is the Sum statement in SQL?) This is one of the aggregate functions (as is count, average, max, min, etc.). They are used in a GROUP BY clause as it ...
  • oracle函数sum()的使用

    千次阅读 2021-05-01 03:53:32
    1、select deptno,ename,sal, sum(sal) over (order by ename) 累计, --按姓名排序,并将薪水逐个累加 sum(sal) over () 总和 , -- 此处sum(sal) over () 等同于sum(sal),求薪水总和 100*round(sal/sum(sal) over...
  • 谈谈go.sum

    千次阅读 2020-02-11 10:58:00
    众所周知,Go 在做依赖管理时会创建两个文件,go.mod 和 go.sum。相比于 go.mod,关于 go.sum 的资料明显少得多。自然,go.mod 的重要性不言而喻,这个文件几乎提供了依赖版本的全部信息。而 go.sum 看上去就是 go ...
  • 对python中矩阵相加函数sum()的使用详解假如矩阵A是n*n的矩阵A.sum()是计算矩阵A的每一个元素之和。A.sum(axis=0)是计算矩阵每一列元素相加之和。A.Sum(axis=1)是计算矩阵的每一行元素相加之和。以上这篇对python中...
  • Matlab中求和函数sum的使用示例

    千次阅读 2021-04-20 05:08:19
    Matlab中求和函数sum的使用示例发布时间:2020-12-23 14:23:12来源:亿速云阅读:56作者:小新这篇文章主要介绍Matlab中求和函数sum的使用示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看...
  • MySQL 使用sum求和

    千次阅读 2022-03-14 20:02:21
    select * sum(custome_field) from self_table where xxx 使用sum的时候后面不能直接加空格 如果加空格会报1630的错 切记
  • python sum_Python sum()

    千次阅读 2020-07-11 05:24:52
    python sumPython sum() function is used to get the sum of numbers of an iterable. Python sum()函数用于获取可迭代数的总和。 Python sum() (Python sum()) Python sum() function syntax is: Python sum...
  • SQL sum函数

    千次阅读 2020-09-25 21:25:59
    SQL sum函数用于统计某一列的和; 原表; 统计paynum列的和; sql对字段可以使用别名,语法是: as xxx;使用别名后如下; 全部运行一下; select * from mempays select SUM(paynum) from mempays...
  • python sum函数怎么用

    千次阅读 2021-01-28 19:02:53
    之前误用sum()函数,我又去查了查python sum()函数才恍然大悟。我本来想算几个Int值相加的和,本以为很简单的事情,结果却很悲伤,例:>>>sum=sum(1,2,3)#结果很明显出现问题报错TypeError:...
  • tf.reduce_sum与torch.sum

    千次阅读 2021-05-26 14:42:52
    dim 参数对应的维数消失 this_platf_target_outputs = torch.reshape(this_platf_target_outputs, shape=(self.batch_size,...this_platf_target_outputs = torch.sum(this_platf_target_outputs, dim=2) # shape=(ba.
  • Python中的sum()详解

    千次阅读 2021-02-03 10:00:25
    sum : sum(iterable, [start=0] ) :求和运算参数说明:iterable:可迭代对象,如列表。start:指定相加的参数,如果没有设置这个值,默认为0list for sum()print(sum([0,1,2])) # 无第二个参数,默认为0 结果=3print...
  • oracle sum()聚合函数

    千次阅读 2021-05-04 08:24:52
    原文链接:https://blog.csdn.net/cizatu5130/article/details/100291347oracle sum()聚合函数2016-05-13 20:08:00 cizatu5130 阅读数 8Oracle 的sum聚合函数的功能就是求和(这里暂时不讨论分析函数用法),一般用法...
  • Mysql - 带条件求和(sum)

    千次阅读 2021-10-13 17:17:47
    select sum(age) from test where age >= 20 如果是 age 小于等于 20 的呢 ? 这还不简单,换下条件就行 select sum(age) from test where age <= 20 但是问题如果是,求 age 大于等于 20,和小于等于 20...
  • MATLAB的sum函数

    千次阅读 2021-07-12 11:24:49
    b=sum(a); a表示行向量,b表示行向量求和的值。 2 a为矩阵 b=sum(a); a表示矩阵,b表示矩阵每列求和得到的行向量。 3 设定sum函数的参数列表的参数dim,对矩阵每一列或者每一列求和或每一行求和,得到行向量...
  • MySQL的sum函数返回的类型

    千次阅读 2021-01-19 01:25:12
    今天项目切换数据库时,出错访问数据库的代码大概是这样:String sql = "select sum(number) as sumNumberOfOneDay from tableName";List rows = getJdbcTemplate().queryForList(sql);for (Map row : rows) {...
  • MySQL中的sum函数用法实例详解

    千次阅读 2021-03-27 19:11:29
    今天分享一下mysql中的sum函数使用。该函数已经成为大家操作mysql数据库中时常用到的一个函数,这个函数统计满足条件行中指定列的和,想必肯定大家都知道了,本身就没什么讲头了,这篇文章主要是通过几个小案例深入...
  • python的sum函数怎么用 ?

    千次阅读 2020-12-07 15:06:30
    sum(iterable[, start]) ,iterable为可迭代对象,如:sum([ ], start) #iterable为list列表sum(( ), start ) #iterable为tuple元组......最后的值 = 可迭代对象里面的数相加的值 + start的值start默认为0,如果不写...
  • MAX-SUM算法

    千次阅读 2020-12-10 21:34:38
    本文的主要目的就是使用MAX-SUM算法在无线传感器网络中使系统的应用获得最佳的性能,一个无线传感器网络的主要结构如下所示: 图2.2 无线传感器网络的基本结构 从图2.2可以看到,无线传感器网络的基本组成可以...
  • Java LongStream sum()用法及代码示例

    千次阅读 2021-02-28 14:05:30
    LongStream sum()返回此流中的元素之和。这是减少的特殊情况。 LongStream sum()是一种终端操作,即,它可以遍历流以产生结果或副作用。注意:归约运算(也称为折叠)采用一系列输入元素,并通过重复应用组合运算(例如...
  • 聊聊 go.sum

    千次阅读 2021-12-29 23:10:51
    1.为什么要引入go.sum 目录 1.为什么要引入go.sum GOPATH(go1.5 版本之前) vendor(go1.5 版本) 2.go.sum的内容 3.GOSUMDB原理 先来看下go的包管理发展历史 GOPATH => vender => go module ...
  • sum函数语法与使用

    千次阅读 2020-11-25 13:40:15
    一、sum 函数语法:SELECT SUM(expression ) FROM tables WHERE predicates;expression常量、列或函数,或者是算术、按位与字符串等运算符的任意组合。expression是精确数字或近似数字数据类型分类(bit数据类型除外...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,361,837
精华内容 944,734
关键字:

sum