精华内容
下载资源
问答
  • 关于group by的用法 原理

    万次阅读 多人点赞 2018-06-14 00:26:30
    写在前面的话:用了好久group by,今天早上一觉醒来,突然感觉group by好陌生,总有个筋别不过来,为什么不能够select * from Table group by id,为什么一定不能是*,而是某一个列或者某个列的聚合函数,group by ...

    写在前面的话:用了好久group by,今天早上一觉醒来,突然感觉group by好陌生,总有个筋别不过来,为什么不能够select * from Table group by id,为什么一定不能是*,而是某一个列或者某个列的聚合函数,group by 多个字段可以怎么去很好的理解呢?不过最后还是转过来了,简单写写吧,大牛们直接略过吧。

    =========正文开始===========

      先来看下表1,表名为test:

     

    表1

      执行如下SQL语句:

    1
    2
    SELECT name FROM test
    GROUP BY name

      你应该很容易知道运行的结果,没错,就是下表2:

     

    表2

      可是为了能够更好的理解“group by”多个列“”聚合函数“的应用,我建议在思考的过程中,由表1到表2的过程中,增加一个虚构的中间表:虚拟表3。下面说说如何来思考上面SQL语句执行情况:

    1.FROM test:该句执行后,应该结果和表1一样,就是原来的表。

    2.FROM test Group BY name:该句执行后,我们想象生成了虚拟表3,如下所图所示,生成过程是这样的:group by name,那么找name那一列,具有相同name值的行,合并成一行,如对于name值为aa的,那么<1 aa 2>与<2 aa 3>两行合并成1行,所有的id值和number值写到一个单元格里面。

     

    3.接下来就要针对虚拟表3执行Select语句了:

    (1)如果执行select *的话,那么返回的结果应该是虚拟表3,可是id和number中有的单元格里面的内容是多个值的,而关系数据库就是基于关系的,单元格中是不允许有多个值的,所以你看,执行select * 语句就报错了。

    (2)我们再看name列,每个单元格只有一个数据,所以我们select name的话,就没有问题了。为什么name列每个单元格只有一个值呢,因为我们就是用name列来group by的。

    (3)那么对于id和number里面的单元格有多个数据的情况怎么办呢?答案就是用聚合函数,聚合函数就用来输入多个数据,输出一个数据的。如cout(id),sum(number),而每个聚合函数的输入就是每一个多数据的单元格。

    (4)例如我们执行select name,sum(number) from test group by name,那么sum就对虚拟表3的number列的每个单元格进行sum操作,例如对name为aa的那一行的number列执行sum操作,即2+3,返回5,最后执行结果如下:

     (5)group by 多个字段该怎么理解呢:如group by name,number,我们可以把name和number 看成一个整体字段,以他们整体来进行分组的。如下图

    (6)接下来就可以配合select和聚合函数进行操作了。如执行select name,sum(id) from test group by name,number,结果如下图:

    至此,我已经对我自己对如此简单的问题有如此天马行空的想法所折服,洗洗睡觉。

    展开全文
  • datax(9):Job和TaskGroup的通讯机制

    万次阅读 2021-01-18 21:49:31
    先后看完了TaskGroupContainer 和 JobContainer...TaskGroupContainer: TaskGroup执行器,负责执行一组Task的工作单元,类似Yarn中的TaskTracker(Yarn中的JobTracker和Yarn中的TaskTracker通过RPC进行通讯); 二.

    先后看完了TaskGroupContainer 和 JobContainer,梳理下他们的关系与职责;


    一、各自职责

    1. JobContainer: Job执行器,负责Job全局拆分、调度、前置语句和后置语句等工作的工作单元。类似Yarn中的JobTracker

    2. TaskGroupContainer: TaskGroup执行器,负责执行一组Task的工作单元,类似Yarn中的TaskTracker(Yarn中的JobTracker和Yarn中的TaskTracker通过RPC进行通讯);


    二、相互关系

    1. TaskGroupContainer向JobContainer上报信息,称JobContainer是TaskGroupContainer的上级;
    2. Task向TaskGroupContainer上报信息,称TaskGroupContainer是Task的上级。

    在这里插入图片描述


    三、TaskGroupContainer向JobContianer汇报过程

    汇报源码逻辑是在TaskGroupContainer#reportTaskGroupCommunication这个方法中,方法的两个形参分别为lastTaskGroupContainerCommunication为上次汇报的信息,每次做数据统计的时候需要将当前communication的数据和lastTaskGroupContainerCommunication进行合并;taskCount为该TaskGroup的所有的任务数。

    1. 收集当前TaskGroupContainer对应所有Task的的communication,然后将其合并成一个communication。
      具体合并代码为步骤1,主要逻辑是在Communication#mergeFrom,它的主要功能将两communication的变量合并。主要关注下两个communication的状态合并,可以看到只要该TaskGroup中有一个Task的状态是FAILED或者KILLED就会将整个TaskGroup的状态标记为FAILED,当且仅当所有的任务的状态是SUCCEEDED,该TaskGroup的状态才能标记为SUCCEEDED。

    2. 生成新的reportCommunication作为该TaskGroupContainer上报给JobContianer的communication,
      主要是生成一些技术统计,比方说当前已经导入的记录数和字节数等。

    3. 上报给JobContianer,主要代码见步骤2,将该TaskGroupContainer最新的communication更新到StandAloneJobContainerCommunicator 能够够的得到的地方,即全局变量LocalTGCommunicationManager#taskGroupCommunicationMap中。

    
      private Communication reportTaskGroupCommunication(Communication lastTGContainerComm,int taskCnt) {
        Communication nowTGContainerComm = this.containerCommunicator.collect();
        nowTGContainerComm.setTimestamp(System.currentTimeMillis());
        Communication reportComm = CommunicationTool
            .getReportCommunication(nowTGContainerComm, lastTGContainerComm, taskCnt);
        this.containerCommunicator.report(reportComm);
        return reportComm;
      }
    

    步骤1

    
    //AbstractCollector#collectFromTask
    public Communication collectFromTask() {
        Communication communication = new Communication();
        communication.setState(State.SUCCEEDED);
    
        for (Communication taskCommunication :
                this.taskCommunicationMap.values()) {
        communication.mergeFrom(taskCommunication);
        }
        return communication;
    }
    Communication#mergeStateFrom
    public synchronized State mergeStateFrom(final Communication otherComm) {
            State retState = this.getState();
            if (otherComm == null) {
                return retState;
            }
    
            if (this.state == State.FAILED || otherComm.getState() == State.FAILED
                    || this.state == State.KILLED || otherComm.getState() == State.KILLED) {
                retState = State.FAILED;
            } else if (this.state.isRunning() || otherComm.state.isRunning()) {
                retState = State.RUNNING;
            }
    
            this.setState(retState);
            return retState;
    }
    
    

    步骤2

    
    // StandaloneTGContainerCommunicator#report
    public void report(Communication communication) {
        super.getReporter().reportTGCommunication(super.taskGroupId, communication);
    }
    
    // ProcessInnerReporter
    public void reportTGCommunication(Integer taskGroupId, Communication communication) {
        LocalTGCommunicationManager.updateTaskGroupCommunication(taskGroupId, communication);
    }
    
    // LocalTGCommunicationManager#updateTaskGroupCommunication
    public static void updateTaskGroupCommunication(final int taskGroupId,
                                                        final Communication communication) {
            Validate.isTrue(taskGroupCommunicationMap.containsKey(
                    taskGroupId), String.format("taskGroupCommunicationMap中没有注册taskGroupId[%d]的Communication," +
                    "无法更新该taskGroup的信息", taskGroupId));
            taskGroupCommunicationMap.put(taskGroupId, communication);
    }
    
    

    四、TaskGroupContainer向JobContianer汇报时机

    TaskGroupContainer向JobContainer汇报该TaskGroupContainer的执行情况的时机均在TaskGroupContainer#start中。

    1、当前TaskGroup中有状态为FAILED或者KILLED的Task

    如果一个Task只能执行一次(默认是1次,没有做重试)且该Task被标记为FAILED或者KILLED,马上将failedOrKilled这个变量标记为true并执行汇报逻辑。这种情况下除了汇报之后,还会抛出一个运行时异常,结束执行当前TaskGroupContainer的线程(TaskGroupContianer是在线程池中执行的)。

    
    if (failedOrKilled) {
        lastTaskGroupContainerCommunication = reportTaskGroupCommunication(
                lastTaskGroupContainerCommunication, taskCountInThisTaskGroup);
    
        throw DataXException.asDataXException(
            FrameworkErrorCode.PLUGIN_RUNTIME_ERROR, lastTaskGroupContainerCommunication.getThrowable());
    }
    
    
    2、上次失败的Task仍未结束

    如果一个Task标记为FAILED或者KILLED,但是有重试逻辑就不会执行上面第1步的逻辑,而是会调用当前的Task对应TaskExecutor#shutdown,关闭当前的TaskExecutor。在调用TaskExecutor#shutdown一段时间发发现给TaskExecutor还没有关闭,触发下面逻辑,进行汇报的同时抛出异常。

    if(now - failedTime > taskMaxWaitInMsec){
        markCommunicationFailed(taskId);
        reportTaskGroupCommunication(lastTaskGroupContainerCommunication, taskCountInThisTaskGroup);
        throw DataXException.asDataXException(CommonErrorCode.WAIT_TIME_EXCEED, "task failover等待超时");
    }
    
    
    3、TaskGroupContainer任务列表为空,所有任务都是成功执行, 搜集状态为SUCCEEDED

    这个没什么好说的,该TaskGroup中所有的任务执行成功,该Job执行成功。

    4、如果当前时间已经超出汇报时间的interval,那么我们需要马上汇报

    可以理解为心跳了

    5、TaskGroupContainer所在的线程正常结束时汇报一次

    这个真没什么好说的了


    五、JobContainer收到汇报之后的处理

    JobContainer的处理逻辑是在dataX所在JVM的主线程中,具体是在AbstractScheduler#schedule中。

    1. 每隔一段时间,合并所有TaskGoupContianer汇报的信息,具体合并的逻辑和TaskGoupContianer合并Task的汇报信息差不多;

    2. 正常结束就正常退出;

    3. 处理isJobKilling,StandAloneScheduler并没有提供kill接口,咱不管;

    4. 重点关注下FAILED的逻辑,直接关闭当前Scheduler的线程池并在主线程中抛出异常,整个dataX进程退出。

    // AbstractScheduler#schedule
    public void schedule(List<Configuration> configurations) {
            ...
            ...
            Communication lastJobContainerCommunication = new Communication();
    
            long lastReportTimeStamp = System.currentTimeMillis();
            try {
                while (true) {
                    Communication nowJobContainerCommunication = this.containerCommunicator.collect();
                    nowJobContainerCommunication.setTimestamp(System.currentTimeMillis());
                    LOG.debug(nowJobContainerCommunication.toString());
    
                    //汇报周期
                    long now = System.currentTimeMillis();
                    if (now - lastReportTimeStamp > jobReportIntervalInMillSec) {
                        Communication reportCommunication = CommunicationTool
                                .getReportCommunication(nowJobContainerCommunication, lastJobContainerCommunication, totalTasks);
    
                        this.containerCommunicator.report(reportCommunication);
                        lastReportTimeStamp = now;
                        lastJobContainerCommunication = nowJobContainerCommunication;
                    }
    
                    errorLimit.checkRecordLimit(nowJobContainerCommunication);
    
                    if (nowJobContainerCommunication.getState() == State.SUCCEEDED) {
                        LOG.info("Scheduler accomplished all tasks.");
                        break;
                    }
    
                    if (isJobKilling(this.getJobId())) {
                        dealKillingStat(this.containerCommunicator, totalTasks);
                    } else if (nowJobContainerCommunication.getState() == State.FAILED) {
                        dealFailedStat(this.containerCommunicator, nowJobContainerCommunication.getThrowable());
                    }
    
                    Thread.sleep(jobSleepIntervalInMillSec);
                }
            } catch (InterruptedException e) {
                // 以 failed 状态退出
                LOG.error("捕获到InterruptedException异常!", e);
    
                throw DataXException.asDataXException(
                        FrameworkErrorCode.RUNTIME_ERROR, e);
            }
    
        }
        
        // ProcessInnerScheduler#dealFailedStat
        public void dealFailedStat(AbstractContainerCommunicator frameworkCollector, Throwable throwable) {
            this.taskGroupContainerExecutorService.shutdownNow();
            throw DataXException.asDataXException(
                    FrameworkErrorCode.PLUGIN_RUNTIME_ERROR, throwable);
        }
    
    


    注:

    1. 对源码进行略微改动,主要修改为 1 阿里代码规约扫描出来的,2 clean code;

    2. 所有代码都已经上传到github(master分支和dev),可以免费白嫖

    展开全文
  • oracle的 listagg() WITHIN GROUP () 行转列函数的使用

    万次阅读 多人点赞 2018-07-11 18:12:25
    如需转载请标明出处 1.使用条件查询 查询部门为20的员工列表 -- 查询部门为20的员工列表 SELECT t.DEPTNO,t.ENAME ...2.使用 listagg() WITHIN GROUP () 将多行合并成一行(比较常用) SELECT T .DEPTNO, li...

    如需转载请标明出处

    1.使用条件查询 查询部门为20的员工列表

    -- 查询部门为20的员工列表
    SELECT t.DEPTNO,t.ENAME FROM SCOTT.EMP t where t.DEPTNO = '20' ;

        效果:

    2.使用  listagg() WITHIN GROUP ()  将多行合并成一行(比较常用)

    SELECT
    	T .DEPTNO,
    	listagg (T .ENAME, ',') WITHIN GROUP (ORDER BY T .ENAME) names
    FROM
    	SCOTT.EMP T
    WHERE
    	T .DEPTNO = '20'
    GROUP BY
    	T .DEPTNO

        效果:

    3. 使用 listagg() within GROUP () over  将多行记录在一行显示(没有遇到过这种使用场景)

    SELECT
    	T .DEPTNO,
    	listagg (T .ENAME, ',') WITHIN GROUP (ORDER BY T .ENAME)  over(PARTITION BY T .DEPTNO)
    FROM
    	SCOTT.EMP T
    WHERE
    	T .DEPTNO = '20' 

        效果:

            注:使用的表数据是oracle 用户scott下的emp(员工)表

     

    mysql相同效果的实现  https://blog.csdn.net/sinat_36257389/article/details/95052001

    PostgreSQL 相同效果的实现 https://blog.csdn.net/sinat_36257389/article/details/95611686

    展开全文
  • groupby函数详解

    万次阅读 多人点赞 2019-06-06 13:40:19
    pandas中groupby函数用法详解1 groupby()核心用法2 groupby()语法格式3 groupby()参数说明4 groupby()典型范例 1 groupby()核心用法 (1)根据DataFrame本身的某一列或多列内容进行分组聚合,(a)若按某一列聚合...

    计算各列数据总和并作为新列添加到末尾

    df['Col_sum'] = df.apply(lambda x: x.sum(), axis=1)
    

    计算指定列下每行数据的总和并作为新列添加到末尾

     df_sf['item_sum'] = df_sf.loc[:,['item_1','item_2','item_3']].apply(lambda x:x.sum(),axis=1)   #'item_sum'列计算'item_1','item_2','item_3'三列的总和
    

    计算各行数据总和并作为新行添加到末尾

    df.loc['Row_sum'] = df.apply(lambda x: x.sum())
    

    计算指定列下各行数据总和并作为新行添加到末尾

    MT_fs.loc['总计']=MT_fs.loc[:,['发货量','签收量','激活量','首充']].apply(lambda x: x.sum())  #“总计”表示新增行的“index”
    

    Table1 groupby()的常见用法

    函数 适用场景 备注
    df.groupby(‘key1’) 一列聚合 分组键为列名(可以是字符串、数字或其他Python对象)
    df.groupby([‘key1’,‘key2’]) 多列聚合 分组键为列名引入列表list[]
    df[‘data1’].groupby(df[‘key1’]).mean() 按某一列进行一重聚合求均值 分组键为Series
    A=df[‘订单编号’].groupby([ df[‘运营商’], df[‘分类’], df[‘百度圣卡’] ]).count() 按某一列进行多重聚合计数 分组键为Series引入列表list[]
    df[‘data1’].groupby([states,years]).mean() 分组键与原df无关,而是另外指定的任何长度适当的数组 分组键是数组,state和year均为数组

    备注:

    grouped=df['data1'].groupby(df['key1'])    #聚合后不适用配合函数的输出为:<pandas.core.groupby.generic.SeriesGroupBy object at 0x000001FE3D1FE5C0>
    

    这是由于变量grouped是一个GroupBy对象,它实际上还没有进行任何计算,只是含有一些有关分组键df[‘key1’]的中间数据而已,然后我们可以调用配合函数(如:.mean()方法)来计算分组平均值等。
      因此,一般为方便起见可直接在聚合之后+“配合函数”,默认情况下,所有数值列都将会被聚合,虽然有时可能会被过滤为一个子集
      一般,如果对df直接聚合时,
    df.groupby([df['key1'],df['key2']]).mean()分组键为:Series)与df.groupby(['key1','key2']).mean()分组键为:列名)是等价的,输出结果相同。
      但是,如果对df的指定列进行聚合时,
    df['data1'].groupby(df['key1']).mean()分组键为:Series),唯一方式。
    此时,直接使用“列名”作分组键,提示“Error Key”。
       注意:分组键中的任何缺失值都会被排除在结果之外。

    1 groupby()核心用法

    (1)根据DataFrame本身的某一列或多列内容进行分组聚合,(a)若按某一列聚合,则新DataFrame将根据某一列的内容分为不同的维度进行拆解,同时将同一维度的再进行聚合,(b)若按某多列聚合,则新DataFrame将是多列之间维度的笛卡尔积,即:新DataFrame具有一个层次化索引(由唯一的键对组成),例如:“key1”列,有a和b两个维度,而“key2”有one和two两个维度,则按“key1”列和“key2”聚合之后,新DataFrame将有四个group;
    注意:groupby默认是在axis=0上进行分组的,通过设置axis=1,也可以在其他任何轴上进行分组。

    (2)groupby(),根据分组键的不同,有以下4种聚合方法:

    • 分组键为Series
      (a)使用原df的子列作为Series
      df.groupby([ df[‘key1’], df[‘key2’] ]).mean()
      (b)使用自定义的Series
      mapping={‘a’:‘red’,‘b’:‘red’,‘c’:‘blue’,‘d’:‘blue’,‘e’:‘red’,‘f’:‘orange’}
      map_series=pd.Series(mapping)
      people.groupby(map_series,axis=1).count()
    • 分组键为列名
      df.groupby([ ‘key1’,‘key2’ ]).mean()
    • 分组键为数组
      states=np.array([‘Ohio’, ‘California’, ‘California’, ‘Ohio’, ‘Ohio’])
      years=np.array([2004,2005,2006,2005,2006]) #自定义数组
      df[‘data1’].groupby( [ states,years ] ).mean()
    • 分组键为字典
      mapping={‘a’:‘red’,‘b’:‘red’,‘c’:‘blue’,‘d’:‘blue’,‘e’:‘red’,‘f’:‘orange’} #自定义字典
      by_column=people.groupby(mapping,axis=1).sum() #指定axis=1,表示对列数据进行聚合分组
    • 分组键为函数
      例如:传入len函数(可以求取一个字符串长度数组),实现根据字符串的长度进行分组
      people.groupby(len).sum() #将字符串长度相同的行进行求和
    • 分组键为函数和数组、列表、字典、Series的组合
      引入列表list[ ] 将函数跟数组、列表、字典、Series混合使用作为分组键进行聚合,因为任何东西最终都会被转换为数组
      key_list=[‘one’,‘one’,‘one’,‘two’,‘two’] #自定义列表,默认列表顺序和df的列顺序一致
      people.groupby([ len,key_list ]).min()
    • 分组键为具有多重列索引df 的列索引层次
      hier_df.groupby(level=‘cty’,axis=1).count() #利用参数level,指明聚合的层级
      (3)常用配合函数/方法
    1. 打印出按某一指定列进行聚合的DataFrame:
    for i in df.groupby('key1'):
        print(i)
    
    1. 按某一指定列进行聚合的DataFrame:

    Table1 groupby()的配合函数

    函数 适用场景 备注
    .mean() 均值
    .count() 计数
    .min() 最小值
    .mean().unstack() 求均值,聚合表的层次索引不堆叠
    .size() 计算分组大小 GroupBy的size方法,将返回一个含有分组大小的Series
    .apply()
    .agg()

    (4)对聚合后的数据片段,进行字典、列表等格式转化

    • 将数据片段转为字典
    pieces=pieces=dict(list(df.groupby('key1')))
    
    • 将数据片段转为列表
    pieces=list(df.groupby('key1'))
    

    (5)利用groupby,根据dtypes对列进行分组,此时需指定axis=1,否则,groupby默认根据axis=0进行分组,而行数据由于类型不统一,故无法根据dtypes对列进行分组,结果为空。
    (6)可使用一个/组列名,或者一个/组字符串数组对由DataFrame产生的GroupBy对象,进行索引,从而实现选取部分列进行聚合的目的即:

    1)根据key1键对data1列数据聚合
    df.groupby('key1')['data1'].mean()
    #或者
    df['data1'].groupby(df['key1']).mean()    #或者df['data1'].groupby([df['key1']]).mean() ,当按多个层次聚合时引入列表,故单层次用列表也无妨
    >>>
    key1
    a    -0.048502
    b     0.053162
    Name: data1, dtype: float64
    (2)根据key1键对data2列数据聚合
    df.groupby('key1')['data2'].mean()
    #或者
    df['data2'].groupby(df['key1']).mean()
    >>>
    key1
    a     -0.533444
    b     -0.948798
    Name: data2, dtype: float64
    (3)根据key1键对data2列数据聚合,当对多列数据如data1和data2根据某个键入key1聚合分组时,组引入列表['data1','data2'],此处对data2外加中括号是一个意思,只是影响输出格式。
    df.groupby('key1')[['data2']].mean()
    #或者df[['data2']].groupby(df['key1']).mean()
    >>>
    	 data2
    key1	
    a	-0.533444
    b	-0.9487984)根据key1键对data1和data2列数据聚合
    df.groupby('key1')[['data1','data2']].mean()
    #或者
    df[['data1','data2']].groupby(df['key1']).mean()
    >>>
    	   data1	data2
    key1		
    a	 -0.048502	-0.533444
    b	  0.053162	-0.9487985)根据多个键key1、key2对data2列数据聚合
    df.groupby(['key1','key2'])['data2'].mean()
    #或者
    df['data2'].groupby([df['key1'],df['key2']]).mean()
    >>>
    key1  key2
    a     one    -1.391653
          two     1.182974
    b     one    -1.707349
          two    -0.190247
    Name: data2, dtype: float64
    

    2 groupby()语法格式

    DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, **kwargs)
    

    3 groupby()参数说明

    by : mapping, function, label, or list of labels
    Used to determine the groups for the groupby. If by is a function, it’s called on each value of the object’s index. If a dict or Series is passed, the Series or dict VALUES will be used to determine the groups (the Series’ values are first aligned; see .align() method). If an ndarray is passed, the values are used as-is determine the groups. A label or list of labels may be passed to group by the columns in self. Notice that a tuple is interpreted a (single) key.

    axis : {0 or ‘index’, 1 or ‘columns’}, default 0
    Split along rows (0) or columns (1).

    level : int, level name, or sequence of such, default None
    If the axis is a MultiIndex (hierarchical), group by a particular level or levels.

    as_index : bool, default True
    For aggregated output, return object with group labels as the index. Only relevant for DataFrame input. as_index=False is effectively “SQL-style” grouped output.

    sort : bool, default True
    Sort group keys. Get better performance by turning this off. Note this does not influence the order of observations within each group. Groupby preserves the order of rows within each group.

    group_keys : bool, default True
    When calling apply, add group keys to index to identify pieces.

    squeeze : bool, default False
    Reduce the dimensionality of the return type if possible, otherwise return a consistent type.

    observed : bool, default False
    This only applies if any of the groupers are Categoricals. If True: only show observed values for categorical groupers. If False: show all values for categorical groupers.

    New in version 0.23.0.

    **kwargs
    Optional, only accepts keyword argument ‘mutated’ and is passed to groupby.

    4 groupby()典型范例

    范例一:根据DataFrame本身的某一列或多列内容进行分组聚合

    #创建原始数据集
    import pandas as pd
    import numpy as np
    
    df=pd.DataFrame({'key1':['a','a','b','b','a'],
                     'key2':['one','two','one','two','one'],
                      'data1':np.random.randn(5),
                      'data2':np.random.randn(5)})
    #'key1':['a','a','b','b','a']亦可写作'key1':list('aabba'),完成列表的创建
    >>> df
       key1	 key2	    data1	  data2
    0	a	 one	  -0.484689	  -3.105627
    1	a	 two	  0.033929	  1.182974
    2	b	 one	  1.067201	  -1.707349
    3	b	 two	  -0.960876	  -0.190247
    4	a	 one	  0.305254	  0.322322
    #(1)按指定的某一列进行聚合
    for i in df.groupby('key1'):
        print(i)
    >>>
    ('a',   key1   key2     data1      data2
    0        a     one     -0.484689   -3.105627
    1        a     two     0.033929    1.182974
    4        a     one     0.305254    0.322322)
    ('b',   key1   key2     data1      data2
    2        b     one     1.067201    -1.707349
    3        b     two     -0.960876   -0.190247)
    #(2)按多列进行聚合,新的DataFrame是多列之间维度的笛卡尔积
    for i in df.groupby(['key1','key2']):
        print(i)
    >>>
    (('a', 'one'),   key1    key2     data1      data2
          0          a       one      -0.484689  -3.105627
          4          a       one      0.305254   0.322322)
    (('a', 'two'),   key1    key2     data1     data2
          1          a       two      0.033929   1.182974)
    (('b', 'one'),   key1    key2     data1     data2
          2          b       one      1.067201 -1.707349)
    (('b', 'two'),   key1   key2     data1     data2
          3          b       two      -0.960876 -0.190247)
    #(3) 按key1进行分组,并计算data1列的平均值
    df1=df['data1'].groupby(df['key1']).mean()
    >>>
    key1
    a       -0.048502
    b       0.053162
    #(4) 按key1、key2进行分组,并计算data1列的平均值,聚合表不堆叠
    #将数据从“花括号”格式转为“表格”格式,unstack即“不要堆叠”
    df2=df['data1'].groupby([df['key1'],df['key2']]).mean().unstack()
    >>>df2
    key2	one	        two
    key1		
    a	    -0.089718	 0.033929
    b	    1.067201	 -0.960876
    #(5)分组键可以是与原df无关的,另外指定的任何长度适当的数组,新数组按列表顺序分别与df[col_1]的数据一一对应。
    states=np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio'])
    years=np.array([2004,2005,2006,2005,2006])
    df['data1'].groupby([states,years]).mean()
    >>>
    California  2005    0.033929
                2006    1.067201
    Ohio        2004   -0.484689
                2005   -0.960876
                2006    0.305254
    #用到GroupBy的size方法,它可以返回一个含有分组大小的Series
    df.groupby(['key1','key2']).size()
    >>>
          key1  key2
    a     one     2
          two     1
    b     one     1
          two     1
    

    范例二:利用for循环,对分组进行迭代

    #原始数据集与范例一相同
    #对一列聚合,使用for循环进行分组迭代
    for name,group in df.groupby('key1'):
        print(name)
        print(group)
    >>>
    a
      key1 key2     data1     data2
    0    a  one -0.484689 -3.105627
    1    a  two  0.033929  1.182974
    4    a  one  0.305254  0.322322
    b
      key1 key2     data1     data2
    2    b  one  1.067201 -1.707349
    3    b  two -0.960876 -0.190247
    #若仅使用一个变量name,会影响输出结果的索引层次表达方式,且结果为元组
    for name in df.groupby('key1'):
        print(name)
    >>>
    ('a',   key1 key2     data1     data2
    0    a  one -0.484689 -3.105627
    1    a  two  0.033929  1.182974
    4    a  one  0.305254  0.322322)
    ('b',   key1 key2     data1     data2
    2    b  one  1.067201 -1.707349
    3    b  two -0.960876 -0.190247)
    #对于多重键的情况,元组的第一个元素将会是由键值组成的元组,所以for循环的第一个变量用元组(k1,k2):
    for (k1,k2),group in df.groupby(['key1','key2']):
        print(k1,k2)
        print(group)
    >>>
    a one
      key1 key2     data1     data2
    0    a  one -0.484689 -3.105627
    4    a  one  0.305254  0.322322
    a two
      key1 key2     data1     data2
    1    a  two  0.033929  1.182974
    b one
      key1 key2     data1     data2
    2    b  one  1.067201 -1.707349
    b two
      key1 key2     data1     data2
    3    b  two -0.960876 -0.190247
    #对于多重键的情况,若for循环的第一个变量不用元组(k1,k2),而是普通变量name,则输出结果的层次索引将为元组格式
    for name,group in df.groupby(['key1','key2']):
        print(name)
        print(group)
    >>>
    ('a', 'one')
      key1 key2     data1     data2
    0    a  one -0.484689 -3.105627
    4    a  one  0.305254  0.322322
    ('a', 'two')
      key1 key2     data1     data2
    1    a  two  0.033929  1.182974
    ('b', 'one')
      key1 key2     data1     data2
    2    b  one  1.067201 -1.707349
    ('b', 'two')
      key1 key2     data1     data2
    3    b  two -0.960876 -0.190247
    

    范例三:对聚合后的数据片段,进行格式类型转化

    #将数据片段转为字典
    pieces=dict(list(df.groupby('key1')))
    >>>
    pieces
    {'a':   key1  key2     data1     data2
     0       a   one     -0.484689 -3.105627
     1       a   two      0.033929  1.182974
     4       a   one      0.305254  0.322322, 'b':   key1 key2     data1     data2
     2       b   one      1.067201 -1.707349
     3       b   two     -0.960876 -0.190247}
     >>>
     pieces['b']    #选取片段
        key1	key2	data1	    data2
    2	b	    one	    1.067201	-1.707349
    3	b	    two	    -0.960876	-0.190247
    #将数据片段转为列表
    pieces=list(df.groupby('key1'))
    >>>
    pieces
    [('a',   key1 key2     data1     data2
      0       a   one     -0.484689 -3.105627
      1       a   two      0.033929  1.182974
      4       a   one      0.305254  0.322322), ('b',   key1 key2     data1     data2
      2       b   one      1.067201 -1.707349
      3       b   two     -0.960876 -0.190247)]
    

    范例四:利用groupby,根据dtypes对列进行分组,此时,需指定axis=1,否则,groupby默认根据axis=0进行分组,而行数据由于类型不统一,故无法根据dtypes对列进行分组

    #df.dtypes用于确定df的数据类型
    df.dtypes
    >>>
    key1      object
    key2      object
    data1    float64
    data2    float64
    dtype: object
    #将聚合后df转化为字典格式,后根据df的数据类型对列进行分组
    grouped=df.groupby(df.dtypes,axis=1)
    dict(list(grouped))
    >>>
    {dtype('float64'):       data1     data2
                          0 -0.484689 -3.105627
                          1  0.033929  1.182974
                          2  1.067201 -1.707349
                          3 -0.960876 -0.190247
                          4  0.305254  0.322322, dtype('O'):   key1  key2
                                                           0    a   one
                                                           1    a   two
                                                           2    b   one
                                                           3    b   two
                                                           4    a   one}
    #若不指定axis=1,则默认groupby根据行数据按dtypes进行分组
    grouped1=df.groupby(df.dtypes)
    dict(list(grouped1))
    >>>
    {}    #由于行数据不统一,故按dtypes分组时,为空
    #将聚合数据片段转化为list类型
    list(grouped)
    >>>
    [(dtype('float64'),       data1     data2
                           0  -0.484689 -3.105627
                           1   0.033929  1.182974
                           2   1.067201 -1.707349
                           3  -0.960876 -0.190247
                           4   0.305254  0.322322), (dtype('O'),    key1  key2
                                                                 0    a  one
                                                                 1    a  two
                                                                 2    b  one
                                                                 3    b  two
                                                                 4    a  one)]
                                                                 
    

    范例五:根据自定义字典、自定义列表、自定义Series、函数或者函数与自定义数组、列表、字典、Series的组合,作为分组键进行聚合

    #创建原始数据集
    people=pd.DataFrame(np.random.randn(5,5),columns=list('abcde'),index=['Joe','Steve','Wes','Jim','Travis'])
    people
    >>>
                a	        b	        c	       d	       e
    Joe 	-0.350379	-2.216265	-1.922898	0.655574	0.512573
    Steve	-1.212107	-1.040184	-0.659978	-0.277454	0.613489
    Wes	    -1.624845	-0.432863	-0.211577	0.310541	2.138030
    Jim	     2.038365	-0.237121	-0.392664	-0.480918	1.566855
    Travis	-0.345361	-0.653787	-0.299217	1.019871	0.511216
    #利用people.ix[2:3,['b','c']]=np.nan,将第2,3行,第b,c列的数据置为空
    people.ix[2:3,['b','c']]=np.nan
    >>>
    people
                a	        b	        c	       d	      e
    Joe	    -0.350379	-2.216265	-1.922898	 0.655574	0.512573
    Steve	-1.212107	-1.040184	-0.659978	-0.277454	0.613489
    Wes	    -1.624845	   NaN	       NaN	     0.310541	2.138030
    Jim	     2.038365	-0.237121	-0.392664	-0.480918	1.566855
    Travis	-0.345361	-0.653787	-0.299217	 1.019871	0.511216
    # 假设已知列的分组关系,并希望根据分组计算列的总计:
    #创建分组的映射字典
    mapping={'a':'red','b':'red','c':'blue','d':'blue','e':'red','f':'orange'}
    mapping
    >>>
    {'a': 'red', 'b': 'red', 'c': 'blue', 'd': 'blue', 'e': 'red', 'f': 'orange'}
    type(mapping)
    >>>
    dict
    #将这个字典传给groupby即可,由于是按列进行分组,指定axis=1
    by_column=people.groupby(mapping,axis=1).sum()
    by_column
    >>>
    	        blue	red
    Joe	       -1.267323	-2.054071
    Steve	   -0.937431	-1.638802
    Wes	        0.310541	 0.513184
    Jim	       -0.873581	 3.368099
    Travis	    0.720653	-0.487932
    #用自定义Series作为分组键进行聚合,则pandas会检查Series以确保其索引跟分组轴是对齐的
    #自定义Series作为分组键
    map_series=pd.Series(mapping)
    >>>
    map_series
    a       red
    b       red
    c      blue
    d      blue
    e       red
    f    orange
    dtype: object
    #用自定义Series作为分组键聚合
    people.groupby(map_series,axis=1).count()
    >>>
           blue	red
    Joe	    2	3
    Steve	2	3
    Wes	    1	2
    Jim	    2	3
    Travis	2	3
    #用函数作分组键,进行分组,需传入len函数(可以求取一个字符串长度数组),实现根据人名的长度进行分组
    people.groupby(len).sum()   #将名字长度相同的行求和
    >>>
            a	        b	         c	        d	       e
    3	0.063140	-2.453386	-2.315561	0.485198	4.217458
    5	-1.212107	-1.040184	-0.659978	-0.277454	0.613489
    6	-0.345361	-0.653787	-0.299217	1.019871	0.511216
    #将函数和数组、列表、字典、Series组合作为分组键,进行聚合
    key_list=['one','one','one','two','two']   #自定义列表,默认列表的字符串顺序和df的列顺序一致
    people.groupby([len,key_list]).min()
    >>>
                 a	        b	        c	        d	       e
    3	one	 -1.624845	-2.216265	-1.922898	0.310541	0.512573
        two	  2.038365	-0.237121	-0.392664	-0.480918	1.566855
    5	one	 -1.212107	-1.040184	-0.659978	-0.277454	0.613489
    6	two	 -0.345361	-0.653787	-0.299217	1.019871	0.511216
    

    范例六:df含有多重列索引的聚合分组

    #根据df的多重列索引的层次级别分组聚合
    #自定义列层次索引
    columns=pd.MultiIndex.from_arrays([['US','US','US','JP','JP'],[1,3,5,1,3]],names=['cty','tenor'])
    >>>
    columns
    MultiIndex(levels=[['JP', 'US'], [1, 3, 5]],
               codes=[[1, 1, 1, 0, 0], [0, 1, 2, 0, 1]],
               names=['cty', 'tenor'])
    #创建包含多重列索引的原始数据集
    hier_df=pd.DataFrame(np.random.randn(4,5),columns=columns)
    >>>
    hier_df
    cty	    US	        JP
    tenor	  1	          3	         5	         1	        3
    0	  0.023254	 -0.271758	-0.129695	-1.003850	0.600698
    1	  -0.076856	 0.696218	-1.054670	-0.232982	0.641908
    2	  0.211017	 0.481233	-0.289600	0.794614	-0.910464
    3	  1.069144	 0.358034	0.169202	-1.910069	0.769219
    #按列索引层次进行分组聚合
    hier_df.groupby(level='cty',axis=1).count()    #利用参数level,指明聚合的层级
    >>>
    cty	JP	US
    0	2	3
    1	2	3
    2	2	3
    3	2	3
    
    #"盲投"DataFrame按照“号码归属省”对指定4列“'发货量','签收量','激活量','首充'”进行聚合
    functions=['count']
    MT_fs_grouped=MT_data.groupby(['号码归属省'])
    MT_fs=MT_fs_grouped['发货量','签收量','激活量','首充'].agg(functions)
    MT_fs=pd.DataFrame(MT_fs)
    MT_fs.reset_index(inplace=True)   #将聚合表的index转为普通列
    #对聚合表增加“各列统计求和”的行,同时指定参与求和的列,即“号码归属省”列需排除;
    MT_fs.loc['总计']=MT_fs.loc[:,['发货量','签收量','激活量','首充']].apply(lambda x: x.sum())
    MT_fs.loc['总计',['号码归属省']]='总计'  #补全“省份”最后一行的“总计”名称
    

    参考链接:https://www.cnblogs.com/huiyang865/p/5577772.html

    5 groupby常见的调用函数

    • 描述组内数据的基本统计量:A.groupby("性别").describe().unstack()
    • 组内均值计算:A.groupby("性别").mean()
    • 我们还可以一次运用多个函数计算:A.groupby( ["班级","性别"]).agg([np.sum, np.mean, np.std]) # 一次计算了三个
    • 按照【生日】的【年份】进行分组,看看有多少人是同龄?
      A[“生日”] = pd.to_datetime(A[“生日”],format ="%Y/%m/%d") # 转化为时间格式
      A.groupby(A["生日"].apply(lambda x:x.year)).count() # 按照【生日】的【年份】分组
      在这里插入图片描述

    参考链接:python中groupby函数主要的作用是进行数据的分组以及分组后地组内运算!

    展开全文
  • group by详解

    万次阅读 多人点赞 2018-09-16 22:06:51
    group_by的意思是根据by对数据按照哪个字段进行分组,或者是哪几个字段进行分组。 二. 语法 select 字段 from 表名 where 条件 group by 字段 或者 select 字段 from 表名 group by 字段 having 过滤条件 ...
  • GROUP BY语句详解

    万次阅读 多人点赞 2019-07-15 23:40:04
    一、group by 的意思为分组汇总。 使用了group by 后,要求Select出的结果字段都是可汇总的,否则就会出错。 group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面。 ...
  • pandas之分组groupby()的使用整理与总结

    万次阅读 多人点赞 2019-07-27 18:41:53
    在使用pandas的时候,有些场景需要对数据内部进行分组处理,如一组全校学生成绩的数据,我们想通过班级进行分组,或者再对班级分组后的性别进行分组来进行分析,这时通过pandas下的groupby()函数就可以解决。...
  • kafka如何删除group

    万次阅读 2016-08-24 00:16:34
    我们在使用kafka消费信息的过程中,不同group的consumer是可以消费相同的信息的,group是在创建consumer时指定的,如果group不存在,会自动创建。其实简单点说就是每个group都会在zk中注册,区别就是注册过还是没...
  • 理解group by

    万次阅读 多人点赞 2017-04-07 15:09:34
    先来看下表1,表名为test:   表1  执行如下SQL语句: 1 ... GROUP BY name ... 可是为了能够更好的理解“group by”多个列“和”聚合函数“的应用,我建议在思考的过程中,由表1到表2的过程中...
  • 5分钟学会MySQL-  "this is incompatible with sql_mode=only_full_group_by"错误解决方案   前言:  一、原理层面  这个错误发生在mysql 5.7 版本及以上版本会出现的问题...
  • ThreadGroup

    千次阅读 2018-10-17 10:17:23
    本文不会对ThreadGroup如何使用进行分析,而是通过解析ThreadGroup的树形结构实现,以便更好的理解ThreadGroup的设计意义
  • mysql 5.7版本默认的sql配置是:sql_mode=“ONLY_FULL_GROUP_BY”,这个配置严格执行了"SQL92标准"。 很多从5.6升级到5.7时,为了语法兼容,大部分都会选择调整sql_mode,使其保持跟5.6一致,为了尽量兼容程序。 二、...
  • 真正有效解决ONLY_FULL_GROUP_BY的问题

    万次阅读 多人点赞 2019-09-19 17:26:17
    有效解决ONLY_FULL_GROUP_BY的问题 问题描述 报错 如上图 在mysql 5.7版本下可能会报如下错误 Error Code: 1055. Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column ...
  • mysql出现which is not functionally dependent on columns in GROUP BY clause报错欢迎使用Markdown编辑器总结 欢迎使用Markdown编辑器 假设查询语句是下面这样: SELECT d_1 FROM table WHERE id = 1 GROUP ...
  • Group Normalization

    千次阅读 2018-03-26 18:40:43
    FAIR 团队,吴育昕和恺明大大的新作Group Normalization。主要的优势在于,BN会受到batchsize大小的影响。如果batchsize太小,算出的均值和方差就会不准确,如果太大,显存又可能不够用。而GN算的是channel方向每个...
  • 【SQL】通俗易懂透过GROUP BY,理解SQL子句优先级

    千次阅读 多人点赞 2020-04-09 21:52:16
    优先级3.1 第一级 FROM, WHEREFROMWHERE3.2 第二级 GROUP BY, HAVINGGROUP BYHAVING3.3 第三级 ORDER BY3.4 第四级 SELECT4. 总结5. 示例 1. 引言 在学习GROUP BY子句时,可能难理解它到底在干嘛,仅仅知道是对数据...
  • Group by函数

    千次阅读 2020-03-20 21:48:39
    Group by函数 1.前言 在数据库操作中分组操作经常用到。本文就来聊一聊,数据库中分组函数GROUP BY ; 2.创建测试表 示例表 CREATE TABLE `group_by_test` ( `id` INT ( 10 ) NOT NULL AUTO_INCREMENT COMMENT '...
  • ConstraintLayout之Group

    千次阅读 2019-07-30 18:14:39
    文章目录ConstraintLayout 之 Group ConstraintLayout 之 Group 关于Group的基本使用如下: <androidx.constraintlayout.widget.Group android:layout_width="wrap_content" android:layout_height="wrap...
  • mysql 统计 group by 之后的 group 的个数

    千次阅读 2018-06-27 10:16:00
    如果将 count(*) 和 group by 一起使用,count(*) 统计的将会是每个 group 里面的行数,而不是 group 的个数。 如果你想统计 group 的个数,需要将 group by 查询放到子查询里面,然后在主查询里面再使用 count(*)...
  • Python中的groupby分组

    万次阅读 多人点赞 2018-06-05 21:02:03
    写在前面:之前我对于groupby一直都小看了,而且感觉理解得不彻底,虽然在另外一篇文章中也提到groupby的用法,但是这篇文章想着重地分析一下,并能从自己的角度分析一下groupby这个好东西~ OUTLINE 根据表...
  • MySQL对group by原理和理解

    万次阅读 多人点赞 2019-06-03 17:57:18
    写在前面的话:用了好久group by,今天早上一觉醒来,突然感觉group by好陌生,总有个筋别不过来,为什么不能够select * from Table group by id,为什么一定不能是*,而是某一个列或者某个列的聚合函数,group by ...
  • Libgdx之Group

    千次阅读 2016-06-06 22:07:18
    Libgdx之GroupGroup可以说Libgdx中非常好用的一个组件,可以把其余的Actor封装在一起,然后赋予同样的Actions或者Position等。 Group的坐标是从左下角开始的,如果将设置Group.setPosition(0,0) 那么就是从屏幕左下...
  • group分组统计是数据库比较常用的功能,mongodb也不例外。不过相对于普通的增删改查,group操作就略微麻烦一些,这里对group在shell中的操作、使用java原生代码操作以及集成spring进行操作进行一个简单的归纳总结,...
  • SQL函数Group_concat用法

    万次阅读 多人点赞 2019-05-20 21:45:53
    group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符']) SELECT * FROM testgroup 表结构与数据如上 现在的需求就是每个id为一行 在前台每行显示该id所有分数 group_concat ...
  • group by 和 order by 的区别 + 理解过程

    万次阅读 多人点赞 2018-07-25 12:04:16
    order by 和 group by 的区别 order by 和 group by 的区别: 1,order by 从英文里理解就是行的排序方式,默认的为升序。 order by 后面必须列出排序的字段名,可以是多个字段名。 2,group by 从...
  • 1、使用group by分组查询 select exam_no,avg (result) as 平均分 from result_info group by exam_no 查询结果如下: 2、使用group by rollup 和group by cube的结果 select exam_no,avg(result) as 平均...
  • Dataset之OttoGroup:OttoGroup数据集的简介、下载、案例应用之详细攻略 目录 OttoGroup数据集的简介 OttoGroup数据集的下载 OttoGroup数据集的案例应用 OttoGroup数据集的简介 官网:...
  • MySQL的分组查询group by

    万次阅读 2020-09-04 10:46:48
    group by (1)、group by的含义:将查询结果按照1个或多个字段进行分组,字段值相同的为一组。 (2)、group by可用于单字段分组,也可用于多个字段分组。 复制代码select * from employee; +------+------+-------...
  • R语言dplyr包的数据整理、分析函数用法文章连载NO.01 在日常数据处理过程中难免会遇到些难处理的,选取更...本篇涉及到的函数为filter、filter_all()、filter_if()、filter_at()、mutate、group_by、select、summa...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 324,208
精华内容 129,683
关键字:

group