百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

各项工具大pk,分组聚合哪家强? 分组和聚合

bigegpt 2024-09-29 09:18 3 浏览

凹凸们,大家好

先看一个小需求,其实是很常见的分组聚合问题。

今天我将带大家分别使用MySQLExcelPandasVBAPython来实现这个需求。

这么齐全的应该算是全网首发吧!当然也是为了让大家对分组聚合代码层面的实现能够更加熟悉。

MySQL实现分组统计

SQL语句:

SELECT 
  deal_date,
  SUM(IF(AREA= 'A区', 1, 0)) 'A区',
  SUM(IF(AREA= 'B区', 1, 0)) 'B区',
  SUM(IF(AREA= 'C区', 1, 0)) 'C区' 
FROM
  order_info 
GROUP BY deal_date ;

结果:

Excel实现分组统计

首先创建数据透视表:

然后将对应的字段拖动到正确的位置:

然后打开透视表选项取消这两项勾选即可:

Pandas进行分组统计

读取数据:

import pandas as pd

df = pd.read_csv("data.csv", encoding="gb18030")
df

结果:


order_idpricedeal_datearea
0S001102019/1/1A区1S002202019/1/1B区2S003302019/1/1C区3S004402019/1/2A区4S005102019/1/2B区5S006202019/1/2C区6S007302019/1/3A区7S008402019/1/3C区

使用数据透视表操作:

df.pivot_table(values="order_id", index="deal_date",
               columns="area", aggfunc="count", fill_value=0)

上述代码相当于groupby操作:

df.groupby(["deal_date", "area"])["order_id"].count().unstack(1, fill_value=0)

但我一般会这样写:

df.groupby(["deal_date", "area"]).size().unstack(1, fill_value=0)

结果均为:

VBA实现分组统计

经过近1小时的痛苦的尝试,终于编写出了下面这段VBA代码,它模拟实现了分组计数的过程:

Option Explicit
Function is_exists(name As String)
Dim sht As Worksheet
For Each sht In Worksheets
   If sht.name = name Then
      is_exists = True
      Exit Function
   End If
Next
is_exists = False
End Function

Sub 分组统计()
    Dim LastRow, LastCol As Long
    Dim Sh As Worksheet
    'Sh指代当前活动页
    Set Sh = Sheets("data")
    '当前活动页的最后一行
    LastRow = Sh.Cells(Rows.Count, 1).End(xlUp).row
    '当前活动页的最后一列
    LastCol = Sh.Cells(1, Columns.Count).End(xlToLeft).Column
    '定义D为字典
    Dim D As Object
    Set D = CreateObject("Scripting.Dictionary")
    Dim row, i As Integer
    Dim key, value As String
    
    For i = 2 To LastRow
        key = Sh.Cells(i, 3).value
        value = Sh.Cells(i, 4).value
        '如果在字典里
        If Not D.exists(key) Then
            D.Add key, Array(0, 0, 0)
        End If
        row = D(key)
        If value = "A区" Then
            row(0) = row(0) + 1
        ElseIf value = "B区" Then
            row(1) = row(1) + 1
        ElseIf value = "C区" Then
            row(2) = row(2) + 1
        End If
        D(key) = row
    Next
    '调试输出字典存储的内容
    For Each key In D.keys()
        Debug.Print key & "," & Join(D(key), ",")
    Next
    
    Dim sht As Worksheet
    If is_exists("result") Then
        Sheets("result").Delete
    End If
    
    '在最后的位置增加一个sheet作为结果表
    Sheets.Add After:=Sheets(Sheets.Count)
    Set sht = Sheets(Sheets.Count)
    sht.name = "result"
    
    '屏幕刷新=false
    Application.ScreenUpdating = False
    '下面写出数据到结果表中,首先写出标题行
    sht.Range("A1").Resize(1, 4) = Application.Transpose(Array("deal_date", "A区", "B区", "C区"))
    sht.Range("A2").Resize(D.Count, 1) = Application.Transpose(D.keys)
    i = 2
    For Each row In D.items()
        sht.Cells(i, 2).Resize(1, 3) = row
        i = i + 1
    Next
    Application.ScreenUpdating = True
    
End Sub

运行前:

点击按钮运行后:

立即窗口和工作表都看到了正确的结果输出,立即窗口看到重复2次的输出是因为我连续运行了两次。

Python实现分组计数

实现代码:

import csv
from collections import namedtuple

result = {}
columns = ["A区", "B区", "C区"]
areas_map = dict(zip(columns, range(len(columns))))
with open("data.csv", encoding="gb18030") as f:
    f_csv = csv.reader(f)
    headers = next(f_csv)
    resultSet = namedtuple("resultSet", headers)
    for r in f_csv:
        row = resultSet(*r)
        areas = result.setdefault(row.deal_date, [0, 0, 0])
        areas[areas_map[row.area]] += 1
result

结果:

{'2019/1/1': [1, 1, 1], '2019/1/2': [1, 1, 1], '2019/1/3': [1, 0, 1]}

借助Pandas转换为表结构方便查看:

pd.DataFrame.from_dict(result, 'index', columns=["A区", "B区", "C区"])

结果:


A区B区C区
2019/1/11112019/1/21112019/1/3101

下面用Python模拟一下Pandas数据透视表实现分组统计的过程:

import csv
from collections import namedtuple, Counter

result = Counter()
with open("data.csv", encoding="gb18030") as f:
    f_csv = csv.reader(f)
    headers = next(f_csv)
    resultSet = namedtuple("resultSet", headers)
    for r in f_csv:
        row = resultSet(*r)
        result[(row.deal_date, row.area)] += 1
result

结果:

Counter({('2019/1/1', 'A区'): 1,
         ('2019/1/1', 'B区'): 1,
         ('2019/1/1', 'C区'): 1,
         ('2019/1/2', 'A区'): 1,
         ('2019/1/2', 'B区'): 1,
         ('2019/1/2', 'C区'): 1,
         ('2019/1/3', 'A区'): 1,
         ('2019/1/3', 'C区'): 1})

第二步Pandas还需再对这个结果进行重塑才得到最终所需要的结果,具体重塑的过程实际实现较为复杂,但可以借助category的Series模拟实现一下:

indexs = result.keys()
index = pd.Series(map(lambda x: x[0], indexs), dtype='category')
columns = pd.Series(map(lambda x: x[1], indexs), dtype='category')
values = result.values()

data = np.zeros((len(index.cat.categories), len(columns.cat.categories)))
for x, y, v in zip(index.cat.codes, columns.cat.codes, values):
    data[x, y] = v
result = pd.DataFrame(data, index=index.cat.categories,
                      columns=columns.cat.categories, dtype='int8')
result

结果:


A区B区C区
2019/1/11112019/1/21112019/1/3101

总结

其实不管用什么语言和工具,分组聚合统计的核心原理都是:

今天我给大家同时演示了MySQL、Excel、Pandas、VBA和Python实现分组聚合,通过对比,或许大家能自己总结出各项工具的优劣和适用场景。

欢迎你在下方评论区留言,发表你的看法,给大家分享和互动。

相关推荐

有些人能留在你的心里,但不能留在你生活里。

有时候,你必须要明白,有些人能留在你的心里,但不能留在你生活里。Sometimes,youhavetorealize,Somepeoplecanstayinyourheart,...

Python学不会来打我(34)python函数爬取百度图片_附源码

随着人工智能和大数据的发展,图像数据的获取变得越来越重要。作为Python初学者,掌握如何从网页中抓取图片并保存到本地是一项非常实用的技能。本文将手把手教你使用Python函数编写一个简单的百度图片...

软网推荐:图像变变变 一“软”见分晓

当我们仅需要改变一些图片的分辨率、裁减尺寸、添加水印、标注文本、更改图片颜色,或将一种图片转换为另一种格式时,总比较讨厌使用一些大型的图像处理软件,尤其是当尚未安装此类软件时,更是如此。实际上,只需一...

首款WP8.1图片搜索应用,搜照片得资料

首款WP8.1图片搜索应用,搜照片得资料出处:IT之家原创(天际)2014-11-1114:32:15评论WP之家报道,《反向图片搜索》(ReverseImageSearch)是Window...

分享一组美图(图片来自头条)(头条美女头像)

...

盗墓笔记电视剧精美海报 盗墓笔记电视剧全集高清种子下载

出身“老九门”世家的吴邪,因身为考古学家的父母在某次保护国家文物行动时被国外盗墓团伙杀害,吴家为保护吴邪安全将他送去德国读书,因而吴邪对“考古”事业有着与生俱来的兴趣。在一次护宝过程中他偶然获得一张...

微软调整Win11 24H2装机策略:6月起36款预装应用改为完整版

IT之家7月16日消息,微软公司今天(7月16日)发布公告,表示自今年6月更新开始,已默认更新Windows1124H2和WindowsServer2025系统中预装...

谷歌手把手教你成为谣言终结者 | 域外

刺猬公社出品,必属原创,严禁转载。合作事宜,请联系微信号:yunlugongby贾宸琰编译、整理11月23日,由谷歌新闻实验室(GoogleNewsLab)联合Bellingcat、DigD...

NAS 部署网盘资源搜索神器:全网资源一键搜,免费看剧听歌超爽!

还在为找不到想看的电影、电视剧、音乐而烦恼?还在各个网盘之间来回切换,浪费大量时间?今天就教你如何在NAS上部署aipan-netdisk-search,一款强大的网盘资源搜索神器,让你全网资源...

使用 Docker Compose 简化 INFINI Console 与 Easysearch 环境搭建

前言回顾在上一篇文章《搭建持久化的INFINIConsole与Easysearch容器环境》中,我们详细介绍了如何使用基础的dockerrun命令,手动启动和配置INFINICon...

为庆祝杜特尔特到访,这个国家宣布全国放假?

(观察者网讯)近日,一篇流传甚广的脸书推文称,为庆祝杜特尔特去年访问印度,印度宣布全国放假,并举办了街头集会以示欢迎。菲媒对此做出澄清,这则消息其实是“假新闻”。据《菲律宾世界日报》2日报道,该贴子...

一课译词:毛骨悚然(毛骨悚然的意思是?)

PhotobyMoosePhotosfromPexels“毛骨悚然”,汉语成语,意思是毛发竖起,脊梁骨发冷;形容恐惧惊骇的样子(withone'shairstandingonend...

Bing Overtakes Google in China's PC Search Market, Fueled by AI and Microsoft Ecosystem

ScreenshotofBingChinahomepageTMTPOST--Inastunningturnintheglobalsearchenginerace,Mic...

找图不求人!6个以图搜图的识图网站推荐

【本文由小黑盒作者@crystalz于03月08日发布,转载请标明出处!】前言以图搜图,专业说法叫“反向图片搜索引擎”,是专门用来搜索相似图片、原始图片或图片来源的方法。常用来寻找现有图片的原始发布出...

浏览器功能和“油管”有什么关联?为什么要下载

现在有没有一款插件可以实现全部的功能,同时占用又小呢,主题主要是网站的一个外观,而且插件则主要是实现wordpress网站的一些功能,它不仅仅可以定制网站的外观,还可以实现很多插件的功能,搭载chro...