mirror of
https://github.com/cheetahlou/CategoryResourceRepost.git
synced 2025-11-16 22:23:45 +08:00
mod
This commit is contained in:
22
极客时间专栏/Python自动化办公实战课/春节特别放送/春节特别放送1|实体水果店转线上销售的数据统计问题.md
Normal file
22
极客时间专栏/Python自动化办公实战课/春节特别放送/春节特别放送1|实体水果店转线上销售的数据统计问题.md
Normal file
@@ -0,0 +1,22 @@
|
||||
<audio id="audio" title="春节特别放送1|实体水果店转线上销售的数据统计问题" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/05/7b/05d232f3c4af825c38a2e244bb252f7b.mp3"></audio>
|
||||
|
||||
你好,我是尹会生。今天是大年三十儿,先祝你春节快乐。同时我也要为假期还在坚持学习的你点赞。
|
||||
|
||||
春节期间,我为你准备了一个项目作业,帮助你检验第一模块的学习成果。这个作业由3个部分组成,今天,我会介绍项目背景,给出你操作题目,2月13号,我会给出参考思路,在2月16号,我会公布答案。希望你跟着更新节奏,完整地参与进来,巩固你之前的学习成果。
|
||||
|
||||
接下来,我先介绍下项目情况。
|
||||
|
||||
这个题目来自我身边的一个真实案例。我先给你简单介绍下背景:一家实体水果店上了多多买菜后,店里的销售管理系统都没法直接使用实体店的那一套。而且像多多买菜、美团社群现在都只能下载Excel数据表。
|
||||
|
||||
题目是:F水果店由于疫情原因,2020年由实体店改为了线上销售。老板为了进行年终数据统计,需要从在线管理软件下载Excel格式的销售数据,并对销售数据进行处理,分析各个种类的水果受欢迎的程度和库存量,最后录入销售管理系统。不过老板在分析Excel的过程中,遇到了这样一个问题。
|
||||
|
||||
将线上的数据转换为线下数据的时候,由于数据不兼容,必须进行统计和一定格式的调整。首先需要合并Excel,统计全年水果销售量。在Excel中,每个sheet记录了当日的销售数据,每个Excel文件记录了当月的销售数据。图表如下:
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/7f/12/7fb84dcc1e0a4489ae0f9a8b9610a012.png" alt="">
|
||||
|
||||
我给你留两道题目:
|
||||
|
||||
1. 统计出全年每种水果的总销售额。
|
||||
1. 统计出每月销售数量排名Top 3的水果。
|
||||
|
||||
欢迎你在留言区分享你对这道题的想法和思考,我们一起交流、讨论。在2月13日,也就是大年初二这一天,我会把解题思路给你分享出来,供你参考。
|
||||
48
极客时间专栏/Python自动化办公实战课/春节特别放送/春节特别放送2|用自顶至底的思路解决数据统计问题.md
Normal file
48
极客时间专栏/Python自动化办公实战课/春节特别放送/春节特别放送2|用自顶至底的思路解决数据统计问题.md
Normal file
@@ -0,0 +1,48 @@
|
||||
<audio id="audio" title="春节特别放送2|用自顶至底的思路解决数据统计问题" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/ec/a7/ecab6c669ee0e1a9426445f9a82bcaa7.mp3"></audio>
|
||||
|
||||
你好,我是尹会生。今天是大年初二,先祝你春节快乐。
|
||||
|
||||
上节课我策划了一个项目作业,你完成得怎么样了呢?如果你对第一模块的内容掌握了60%,其实这道题你就能完成得差不多了,或者说至少会有一个思路。那么今天这节课,我也来给你提供一些我的解题思路和解题方法。
|
||||
|
||||
我们再来回顾下两道题目:
|
||||
|
||||
1. 统计出全年每种水果的总销售额。
|
||||
1. 统计出每月销售数量排名Top 3的水果。
|
||||
|
||||
因为这两道题目都是需要在统计数据的前提下进行的,一个是统计之后进行求和,一个是统计之后进行排序。所以,我们优先要做的就是统计全部文件所有sheet里的单元格数据。
|
||||
|
||||
**以第一<strong><strong>题**</strong>为例,可以按照自顶至底的思路拆分问题。</strong>
|
||||
|
||||
什么是自顶至底呢?意思是分解问题的时候,先关注总体,再解决具体问题。我给你举个例子你会更容易理解。这是一个你熟悉的问题:怎样把大象装进冰箱?
|
||||
|
||||
你会马上想到,把大象装进冰箱分成三个步骤。你看,你不会关注冰箱是什么品牌,大象是什么品种,冰箱的容积如何,大象的体积有多大等等。这样思考的好处是你可以先对高层次的问题进行定义、设计、编码,再细节的问题,再其中的子任务或下一层次去解决。这样逐层去进行设计和编码能够让你的程序有更好的可读性。
|
||||
|
||||
那统计销售总数,我也可以把问题拆分成三个步骤。
|
||||
|
||||
- 第一步,拆解Excel,通过第二讲的循环功能,取得每日销售数据。
|
||||
- 第二步,读取每天里的每次销售金额数据。
|
||||
- 第三步,将数据按照自己的算法(这里就是简单的累加)进行汇总。
|
||||
|
||||
接下来我带你具体看下每个步骤需要做什么。
|
||||
|
||||
首先,我们来取出每日销售数据。
|
||||
|
||||
你可以先从总销售额开始入手,思考如何拆解问题,。总销售额可以拆分成按月销售额的累加,每月的销售数据可以存放到单独的文件中。月销售额可以拆分成日销售额的累加,日销售额放在每个sheet中。
|
||||
|
||||
如果用python来实现总销售额的统计,实现思路应该为:通过pathlib库和for循环遍历文件,读取每个Excel文件,再通过xlrd库读取每个Excel里的每个sheet,每个sheet里记录了每一天的销售数据,这样可以把每天的销售数据读取出来。
|
||||
|
||||
接着,我们来读取每一次销售数据。
|
||||
|
||||
由于Excel中除了销售金额,还有日期等其他噪声数据,我们只需要读取“水果名称”“销售金额”这两列必须数据,就能实现统计销售总额的功能了。因此通过这两个数据所在的列取出“水果名称”“销售金额”这两列。
|
||||
|
||||
用python实现的话,就是:使用for循环遍历每一行的水果,再采用“字典”数据类型临时存放到Python的一种数据结构中。为什么要使用“字典”呢?在第三讲我给你讲解过,“字典”适合记录有映射关系的一对或多对数据。
|
||||
|
||||
最后,将数据汇总在一起。
|
||||
|
||||
根据需求,销售的金额只需要记录汇总的金额就可以实现最终要求,也就是统计全年销售额的任务了。所以这一步具体做法就是:把字典中可以对每种水果的每次销售金额累加存放,就可以得到当日每种水果销售总金额了。
|
||||
|
||||
第二道题,那如何来实现Top3功能呢?
|
||||
|
||||
这两道问题的处理思路非常相似,都是需要处理每个月的销售额,但是第一个问题,统计全年销售额,需要将12个月的销售数据进行累加。第二个问题,需要对每个月的销售数据进行从大到小的排序,前三位的就是“水果销售Top3”了。
|
||||
|
||||
你的思路和想法是什么呢?可以在留言区分享一下,我们一起交流、讨论。在2月16日,也就是大年初五这一天,我会把完整答案给你分享出来,供你参考。
|
||||
168
极客时间专栏/Python自动化办公实战课/春节特别放送/春节特别放送3|揭晓项目作业的答案.md
Normal file
168
极客时间专栏/Python自动化办公实战课/春节特别放送/春节特别放送3|揭晓项目作业的答案.md
Normal file
@@ -0,0 +1,168 @@
|
||||
<audio id="audio" title="春节特别放送3|揭晓项目作业的答案" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/77/c8/771e1060c93ef2f0d2176d4bef361bc8.mp3"></audio>
|
||||
|
||||
前两节课,我给你策划了一个项目作业,也给你提供了解题思路和方法,那么今天,就是揭晓答案的时候了。不管你有没有完成作业,或者完成了多少,我都建议你在学习今天这节课的时候,一边看我的讲解,一边把你的答案与我讲解的答案进行对照。
|
||||
|
||||
不过我也要提醒你,因为现在你才学到了第三节课,所以答案对你来说并不是最重要的。重要的是你对前三节课的内容掌握了多少,以及这个项目作业的解题思路和方法。
|
||||
|
||||
话不多说,我们现在就开始吧。
|
||||
|
||||
## 第一题
|
||||
|
||||
我们先看第一道题中关于订单统计的处理思路。
|
||||
|
||||
**首先我们要明确要解决的问题。**
|
||||
|
||||
我们希望对多个Excel进行统计,并取得每个Excel文件里的sheet。然后再从每一个sheet当中取出水果的名称和它的每一次销售金额,最终要将多个Excel里的所有的数据进行合并。而合并之后就是我们想要的全年水果销售金额统计结果。
|
||||
|
||||
所以解决这个问题的关键点有两个。
|
||||
|
||||
**第一个关键知识点是遍历。**这个知识点在我们的第1讲、第2讲中都有提到。通过遍历的方式,我们能依次取到每一个文件里的每一个sheet,甚至能从每个sheet取出每一行的内容。
|
||||
|
||||
**第二个关键的知识点就是**<strong>多个元素的累加操作**</strong>。**主要就是把相同名称的水果销售金额进行计算。不过这里涉及到的计算很简单,就是累加操作,通过循环就可以实现多个元素的依次累加了。由于累加是针对每一行数据的,所以我们要把累加操作写在遍历每一行的循环当中。
|
||||
|
||||
在搞清楚了两个关键知识点之后,**接下来我来带你去分析一下<strong><strong>我实现全年销售统计的**</strong>代码。</strong>
|
||||
|
||||
```
|
||||
import xlrd
|
||||
from pathlib import Path, PurePath
|
||||
from collections import defaultdict
|
||||
|
||||
# 订单路径
|
||||
download_path = '/Users/edz/Desktop/效率专栏/新年特辑/订单'
|
||||
|
||||
# 取得该目录下所有的xlsx格式文件
|
||||
p = Path(download_path)
|
||||
files = [x for x in p.iterdir() if PurePath(x).match('*.xlsx')]
|
||||
|
||||
# 定义字典用于结果统计
|
||||
total = defaultdict(int)
|
||||
|
||||
# 中文做字典的key会有问题,做两个简单的翻译函数
|
||||
tran_dict = {
|
||||
"dragon_fruit":"火龙果",
|
||||
"coconut":"椰子",
|
||||
"watermelon":"西瓜"
|
||||
}
|
||||
# 中文翻译成英文
|
||||
def dict_trans_chi2eng(value):
|
||||
return [k for k,v in tran_dict.items() if v == value]
|
||||
|
||||
# 英文翻译成中文
|
||||
def dict_name_eng2chi(key):
|
||||
return tran_dict[key]
|
||||
|
||||
# 遍历文件
|
||||
for file in files:
|
||||
sheet = xlrd.open_workbook(file)
|
||||
|
||||
# 遍历表格
|
||||
for table in sheet.sheets():
|
||||
# 从第二行遍历内容
|
||||
for line in range(1,table.nrows):
|
||||
fruit = table.row_values(rowx=line, start_colx=0, end_colx=None)
|
||||
# 第一列水果名称, 倒数第二列销售金额
|
||||
# print(f'{fruit[0]},{fruit[-2]}')
|
||||
# 火龙果,15.0
|
||||
# 椰子,16.0
|
||||
# 西瓜,10.5
|
||||
|
||||
# 统计每种水果的销售额
|
||||
fruit_name = dict_trans_chi2eng(fruit[0])[0]
|
||||
total[fruit_name] = total[fruit_name] + fruit[-2]
|
||||
|
||||
for fruit_name in total:
|
||||
print(f'水果: {dict_name_eng2chi(fruit_name)} , 总金额: {total[fruit_name]}')
|
||||
|
||||
# 水果: 火龙果 , 总金额: 135.0
|
||||
# 水果: 椰子 , 总金额: 144.0
|
||||
# 水果: 西瓜 , 总金额: 94.5
|
||||
|
||||
```
|
||||
|
||||
我们来看代码的前3行。第1行是读取Excel文件的库,第2行是用来去处理路径的库,这两个库在我们课程的第一讲都已经为你重点讲解过。**读取<strong><strong>E**</strong>xcel使用的是xlrd库, 处理路径需要使用pathlib</strong>。之后的课程你也会多次看到它们,所以没有记住的话一定要再去复习。
|
||||
|
||||
我重点讲解一下第3行出现的库。第3行的库是一个叫做defaultdict的特殊字典。它特殊在哪里呢?**和字典相比****,defaultdict可以在**<strong>字典**</strong>初始化的时候**<strong>得到一个默认的**</strong>值。在我的代码中,就使用defaultdict记录了水果数量,默认把水果数量设置为0,那就不用像默认字典一样,设置了字典之后还要手动把字典的值赋值为0。
|
||||
|
||||
这三行都是程序引入的库,**接下来我们来看具体的代码逻辑**。
|
||||
|
||||
首先我们需要**获得Excel文件所在的路径**。第9、10行代码是用来读取目录下所有的Excel文件的,获取路径使用的是第2讲的pathlib库,我在第2讲也为你详细剖析过它的逻辑,这里就不再赘述了。
|
||||
|
||||
获得路径之后,接着就要去**处理每一个文件**了。从**第30行**开始就是我们**程序的核心逻辑**,像咱们的第二讲一样,我在这里使用了三个for循环。
|
||||
|
||||
- 第1个循环用来遍历所有的Excel文件。
|
||||
- 第2个循环用来遍历所有的sheet。
|
||||
- 第3个循环用来读取文件当中的,第2行到最后一行。
|
||||
|
||||
通过这些循环我就可以按行进行处理。那再接着需要处理的就是**如何进行水果销售金额的累加。**
|
||||
|
||||
如果你仔细观察代码就会发现,我并没有马上去进行累加,而是在这里做了一个**把中文转换成英文的额外处理**,这个额外的处理使用了第三讲学过的**自定义函数功能**。
|
||||
|
||||
你可能会问,为什么要进行中文转换英文呢?因为在Python程序当中,字典这个数据类型对中文支持并不友好,使用中文作为字典的key进行操作时会报错。
|
||||
|
||||
所以为了避免字典在处理中文的时候出现报错,我在这里做了一个**中文英文映射和转换**的一个小功能。这个功能被我写在文件当中的第15到第27行,你会看到这里有一个**被定义为translate_dict的一个映射关系的字典**。
|
||||
|
||||
在这个字典当中,Key就是英文单词,value就是中文汉字。如果在你编写的程序当中需要支持更多的水果种类,那你就可以按照我的格式在这个字典中继续去扩展中英文的映射关系。
|
||||
|
||||
那中英文转换又是怎么实现的呢?我在字典之后又自定义了两个函数,分别被我命名为Chinese to English和English to Chinese。
|
||||
|
||||
在有了中英文转换功能,那我在进行水果的累加之前,“Chinese to English”函数就可以把字典的“key”从中文的水果名称转换成英文。转换成英文,就意味着英文的水果名称可以作为统计总金额的字典total的key。那么:
|
||||
|
||||
- 使用total[fruit_name]方法就可以取得已经统计的水果金额。
|
||||
- 使用fruit[-2]取得通过当前得到的水果金额。
|
||||
- 使用total[fruit_name] = total[fruit_name] + fruit[-2] 方式,就可以实现全年的水果销售总金额统计功能。
|
||||
|
||||
最后,在第49行**把<strong><strong>销售金额统计**</strong>结果进行输出</strong>。由于水果名称在处理过程被处理成英文,为了让你查看的结果更加友好,我还需要再做两件事情。
|
||||
|
||||
1. 第一个是我在输出前把英文的水果名称使用“English to Chinese”函数转换成了中文。
|
||||
1. 第二个是使用了字符串连接功能,将输出的内容进行对齐并增加必要的提示信息,这样你就可以看到每种水果今年的销售总额了。
|
||||
|
||||
以上就是我在实现全年水果销售统计的问题上,是如何编码来实现的。
|
||||
|
||||
## 第二题
|
||||
|
||||
接下来我们再看第二个问题。第二个问题要求你按月进行水果销售额Top3的统计信息,并且取出当月销售数量前三名的水果名称。
|
||||
|
||||
针对这道题,在进行编码之前我们要思考一下,按月统计数据和全年统计数据有什么区别?怎么才能取出销售数量的前三名呢?
|
||||
|
||||
咱们首先来解决按月统计数据和全年统计数据有什么区别这个问题。
|
||||
|
||||
回顾一下我们在解决全年统计问题的过程。我们先取得了每次销售数据。之后又使用了total字典类型,统计了所有行的结果,通过循环,将所有行的结果汇总成日数据和月数据,又继续通过循环将月数据统计为全年销售总额。
|
||||
|
||||
如果需要统计水果销售额Top3,我们也需要先将数据统计为月销售数据,之后不能将月数据合并到一起,而是需要对每个月的数据进行排序,取出销售最多的前三个水果销售额,所以统计月销售数据以前的程序逻辑是相同的,区别是统计月销售数据以后,一个是进行合并一个是进行排序操作。
|
||||
|
||||
那第二个问题,怎样去取前三名呢?我们要想取出前几名,前提是要先进行数据的排序工作。因为排序之后才能从大到小取出销售量最高的前三名。为了实现排序这一功能,我们必须要掌握Python的**排序和截取前三个元素的程序编写方法**。
|
||||
|
||||
所以接下来我们要学习的就是具体编码。由于和统计总金额的代码功能非常相似,我们就直接复用统计总金额的获取文件路径,统计月销售额的代码。由于每一个文件代表一个月份的销售数据,所以我在第48行用输出文件名的方式告诉你当前在统计的文件是哪一个月份的。
|
||||
|
||||
通过上面的逻辑方法,我们实现了按月统计销售额和输出当前月份的功能。接下来就可以进行后续的排序,并且取出字典的value排前3的数据了。你可以通过比较传统的sort函数进行排序,并采用复循环三次取出前3水果名称和销售数量。
|
||||
|
||||
不过我觉得采用这样的方式,代码其实不够简洁。所以我们还有另外一种简洁的方法。
|
||||
|
||||
在程序中,我为了避免自己需要编程实现代码逻辑,就直接引入了collections标准库的Counter包实现排序并提取前n个数的功能。Counter包支持对列表和字典进行排序、数量统计、取前n个数的功能,非常强大。
|
||||
|
||||
那这里就用它来实现基于字典的value从大到小进行排序,排序之后取前三个元素的功能来实现,从而取得水果销售额Top3。
|
||||
|
||||
在代码的第53行,就是我使用了Counter包实现对total变量进行排序的具体实现代码。
|
||||
|
||||
在排序之后,接下来的问题就是如何取出前三个元素了。由于提取前N个元素的问题,Counter包已经内置了该功能,所以在第58行,我可以再通过most_common()函数,为函数增加数字“3”作为参数,从而实现提取销量Top3的功能。
|
||||
|
||||
```
|
||||
# 使用Counter函数排序和统计数量
|
||||
sorted_total = Counter(total)
|
||||
|
||||
# 清空本月统计数据
|
||||
total = defaultdict(int)
|
||||
|
||||
# 通过most_commnon函数排序取出Top3
|
||||
print(sorted_total.most_common(3))
|
||||
|
||||
|
||||
```
|
||||
|
||||
在这个程序当中,我们也有一个要注意的事项。因为每个月份统计好的数据都会放到total变量当中,因此在进行下一个月统计的时候,total变量会把本月统计结果累加上去,这样就会导致下一个月统计的数量不准确。
|
||||
|
||||
所以我们在统计完每一个月的统计数据之后,需要把total变量重新初始化。为了能够让你注意这件事情,我特意把它写在了第56行并详细进行了标注。这也是在进行数据统计时极容易犯错误的地方,希望你能注意它的用法。
|
||||
|
||||
以上就是我实现所有水果的金额统计和按月统计的实现方法,希望你能通过这两个代码理解如何去处理大批量重复的Excel工作。
|
||||
|
||||
好了,我们的春节策划到这节课就结束了,你的答案和我的一样吗?希望你能借助这个项目,查漏补缺,多多巩固前面的内容。下节课,我们继续来自动化办公的方法,我们下次见。
|
||||
Reference in New Issue
Block a user