在前文《合并汇总大量数据表的一般方法》中,我介绍了合并、规范数据表的方法,在《统计数据的清洗和规范化的原则和方法探讨》一文中,我们讨论了数据清洗和规范化的原则和方法,在本文中,我再举例介绍一下统计报表宾栏规范化的一般方法,以及指标分解的思路。
问题的提出
为方便表述,我对原文中的数据源做了简化,假设我们现在有两张数据源表,表1是2011年5月北京市分区社会消费品零售额数据,表2是2019年6月北京市分区社会消费品零售额数据,现在需要对两张表进行合并:
本文以宾栏为例介绍规范化过程,所以甲栏仅保留两个市区以方便表述。
宾栏的变形
规范化数据表首先需要分析表结构的不同,表结构中的宾栏即表头,分析两张表宾栏(表头)的不同,首先是表1的表头占了两行,表2只有一行,但是上一行的表头只是简写,实际上表2的表头还是两行,只是在能看懂的情况下把不必要写明的信息省略了,可以完善如下:
甲栏(项目)、宾栏(表头)的目的是简单明了,方便人们的理解,因此会把相邻的两个相同的单元格合并,也方便对比同类数据,实际上表头占用的两行可以互换,并不影响数据的使用,而且各列数据也可以随意调整顺序,在关系型数据库中,这是列的性质之一。
于是我们可以看出表1、表2的表头的第二个不同之处:与表2相比,表1的第3、4列(数据列的第2、3列)互换了位置,为了方便标注,把表头占用的两行也互换了,规范化数据表的一个原则是要以最新的表结构为准,因此可以把表1加以变化,使之和表2的表结构保持一致:
其中关键的一步是交换两列数据的位置,相应的引起的表头形式的变化只是数据变化的表现和反映,表结构变化的本质还是数据的变化,不是表头的变化。
现在表1和表2的表结构一致了,其实已经可以把两张表合并(拼接在一起)了,但是为了方便数据分析,我们还需要把二维表转换为一致表,所用的方法是逆透视,我们可以看一下表1的表结构变化前后的两种形式的逆透视结果:
什么是逆透视,为什么要进行逆透视?
可以看出,所谓逆透视,就是把多行多列的数据变为多行1列(也就是二维表转一维表),所用的方法就是把各行数据转置之后拼接在一起,相应的表头也需要转置,变为一列或几列属性,逆透视之后的甲栏(在这里是市区)和宾栏都变成了属性,我们就可以方便地对它们进行筛选和用数据透视表进行建模分析了,这就是我们为什么要进行逆透视的原因。
在这个例子中,宾栏包括两个属性:度量和计值,度量有两个:“本年实际(万元)”和“比去年同期增长(%)”,计值也有两个:“本月”和“1-5月累计”,对比表1两种形式逆透视结果可以看出,原表中交换两列数据只是会引起逆透视结果表中列顺序和行顺序的变化,对数据分析结果没有任何影响。
逆透视结果表是一维表,符合数据库报表的要求,可以作为基础报表入库存储,这里的逆透视操作是关系型数据库模式分解的前提和一部分,以后会经常用到。
对于Power BI中的逆透视操作可以参考另一篇文章。
模式分解以后再说,这里需要注意的是模式分解的前提之一:通过逆透视实现的宾栏的指标分解。
数据分析的第一步:指标分解
大部分的统计报表中,甲栏是项目(或称栏目,这里是市区),宾栏是指标,甲栏一般只占用一行,就是第一行,宾栏(表头)经常不止一行,常见的是两行,有时候还可能有三行甚至多行,这个例子中表1的表头占用两行,表2的表头占用1行,但实际上还是两行,只是省略了一行,一行的表头可以变为两行,两行的表头也可变为一行,实际上所有的多行表头都可以变为一行,方法是把多行表头连起来写,采用“……的……的……”的形式,前面提到的表2的第1列数据的表头可写为“2019年6月的本年实际”或“2019年6月的社会消费品零售额”,第2表数据表头可写为“2019年6月的增长率”,那么反过来,一行的表头可以根据内容进行拆分,本例中表2的一行表头可拆分成两行。
表头有几行,就表示着指标有几个属性,逆透视之后可以看得很清楚,实际上本例的4列数据是“计值”和“度量”两个属性的组合,以表2为例,4列数据分别是“当期的绝对值”、“当期的增速”、“累计的绝对值”、累计的增速“”,也就是属性“计值”的两个属性值“当期”和“累计”和属性“度量”的两个属性值“绝对值”和“增速”的相互组合,这叫做两个属性(集合)的“笛卡尔积(直积)”,统计报表宾栏指标的分解就是要把一个指标分解为几个指标的组合(求直积的结果),只要其中几个指标间有相同的性质就可以分解,指标分解是数据分析的基础,分解出的各个组成属性就是数据分析的角度,有大师说过,数据分析就是分类比较的学科,确实如此,分析出整体的各个组成部分,对同类事物进行比较,从而把握事物变化的规律,以指导未来的工作,促进事物的整体发展,这就是数据分析的全部意义所在。
笛卡尔积表1和表2逆透视之后的一维表可以很方便地合并起来,之后的规范化就很简单了:
可以看出,所谓“本月”、“2019年6月”都是“当期值”的意思,“1-5月累计”、“2019年1-6月”都是“累计值”的意思,“比去年同期增长(%)”、“同比增长(%)”都是“增速”的意思,如此等等,只需要根据意思把各属性的属性值替换为统一的名字就可以了。
各属性值就是统计报表的甲栏、宾栏名称,其写法有时候非常随意,我曾尝试建立规范化名称对照表,把诸如“增速”、“增长速度”、“增长率”、“同比增长”等等都转换为“增速”,后来发现不可行,别名实在太多了,永远整理不完,所以我转换思路,用行列号而不是行列名(甲栏、宾栏名称)来进行规范化,同时也可以解决指标分解的难题。具体的过程是这样的:
规范行号(甲栏) 规范列号(宾栏)其中转换的关键是是找到规范表中的主键,也就是属性之间的依赖关系,对于甲栏规范表来说,是“市区”=f(表号, 行号),给定一个表号和行号,就知道它所表示的市区;对于宾栏规范表来说,是“计值x度量”=f(表号, 列号),给定一个表号和列号,就知道它所表示的计值和度量,根据这个规范表进行转换,转换过程使用的方法是“合并查询”,具体请看另一篇文章。
甲栏、宾栏规范表整理
其中用到的甲栏、宾栏规范表都是一维表,和我们平时常见的二维数据表结构不一致,可以通过逆透视把平时整理的二维表转为这种一维表的形式:
可以看出,只需要确保行号、列号没错,至于甲栏、宾栏中写的名称是什么样的都没关系,甚至为空也不影响转换结果。
最后,可以对合并且规范化之后的一维表进行各种透视,转换为我们习惯的样式,例如我们经常透视度量,结果是这样:
规范化结果实例下载:https://pan.baidu.com/s/1VycZfI8vjutE0-sllvBwBw
提取码:am0p
网友评论