数据分析时,同事经常给你一份二维表,是不是分分钟有想哭的冲动,一大堆的东西在一块,怎么透视?想要做进一步分析,也是特别麻烦。今天给你一种方便的方法。
一、入门版
先来看看可能要处理的文件是什么样的?
看看,别提多闹心了。当然我们不可能一开始就处理这么复杂的样式。先来个简单的验证一下。
如上这样一个二维数据,怎么变成一维数据呢?
excel中可以这样操作
-
选择数据透视表,快捷键alt+d+p,这里是用wps的演示的,用office是一样的效果
-
选择多重合并计算区域
-
创建单面字段
-
选择数据区域
-
添加数据区域
-
点击完成,默认新工作表确定
-
这样一个数据透视表就出现了
到这时,读者可能想,还是没有变成一维表呀,这不依然是二维表。别急,还有下面的关键步骤。
-
在透视表的区域里去除行和列的数据,只保留值的区域
这是我们的数据透视表变成了这样:
-
双击数值,我们这里就是这个6762
这时就进入了这样一个界面,相信细心的朋友一定能发现这里正好就是我们要的二维数据了,复制整个内容,更改一下列名。
让我们头痛的二维表就这样变成了一维表。
二、进阶版
完成了这样一个简单的验证,我们再来考虑一下我们开头提到的复杂样式?这个该怎么处理呢?是不是也可以用这种方法解决呢?
先试一试
好像没那么管用了,我们希望的是二级区域,业务员,类型这些也能像一级大区这样展开,可是这里却混在了一起。这可怎么办呢?
Pandas来救场
熟悉python的应该知道,python经常被说成是数据分析的好工具,但是其实python能进入数据分析领域,pandas才是其中最大的功臣,pandas和numpy成为python数据分析最大的法宝。这里我们就要用到pandas的一个很方便的功能。
- 引入相关包
# 引入相关包
import pandas as pd
import numpy as np
- 读入文件
# 读入文件
file = r"E:\销售数据报表项目\医美专题\2dims.xlsx"
df = pd.read_excel(file)
df.head()
数据输出:
一级大区 二级区域 业务员 型号 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
0 南区 浙南区域 name1 type1 222.392385 110.46942 207.566226 208.341450 234.989775 244.680075 239.834925 249.525225 205.918875 276.17355 296.52318 290.709
1 南区 浙南区域 name1 type2 52.166115 25.91258 48.688374 48.870217 55.121058 57.394092 56.257575 58.530608 48.301958 64.78145 69.55482 68.191
2 南区 浙南区域 name2 type1 866.394630 430.36596 808.634988 811.655100 915.471450 953.222850 934.347150 972.098550 802.217250 1075.91490 1155.19284 1132.542
3 南区 浙南区域 name2 type2 203.228370 100.95004 189.679812 190.388233 214.740217 223.595483 219.167850 228.023117 188.174417 252.37510 270.97116 265.658
4 南区 浙南区域 name3 type1 1280.382795 636.00714 1195.023942 1199.487150 1352.909925 1408.700025 1380.804975 1436.595075 1185.539625 1590.01785 1707.17706 1673.703
可以看到,和我们在excel里看到的内容是一致的。
下面我们就要开始变换处理了。
- 变换处理
# 变换处理
df1 = df.set_index(['一级大区','二级区域','业务员','型号'])
df2 = df1.stack()
df3 = df2.reset_index()
df3.columns = ['primary_area', 'sub_area', 'sales_man',
'product_specifications', 'month', 'target']
df3
数据输出:
primary_area sub_area sales_man product_specifications month target
0 南区 浙南区域 name1 type1 1月 222.392385
1 南区 浙南区域 name1 type1 2月 110.469420
2 南区 浙南区域 name1 type1 3月 207.566226
3 南区 浙南区域 name1 type1 4月 208.341450
4 南区 浙南区域 name1 type1 5月 234.989775
5 南区 浙南区域 name1 type1 6月 244.680075
6 南区 浙南区域 name1 type1 7月 239.834925
7 南区 浙南区域 name1 type1 8月 249.525225
8 南区 浙南区域 name1 type1 9月 205.918875
9 南区 浙南区域 name1 type1 10月 276.173550
10 南区 浙南区域 name1 type1 11月 296.523180
11 南区 浙南区域 name1 type1 12月 290.709000
12 南区 浙南区域 name1 type2 1月 52.166115
...
3405 北区 山东大区 name140 type2 10月 127.680000
3406 北区 山东大区 name140 type2 11月 137.088000
3407 北区 山东大区 name140 type2 12月 134.400000
3408 rows × 6 columns
可以看到,二维表已经变成了我们想要的一维表了。
这中间到底发生了什么魔法?
我们来解释下刚刚的代码:
# 变换处理开始
# 首先把数据df设置成多项索引,就像下面这样
df1 = df.set_index(['一级大区','二级区域','业务员','型号'])
# 然后把二维表格变成堆叠样式
df2 = df1.stack()
# 再把堆叠样式的数据重建索引
df3 = df2.reset_index()
# 我们把原来一行的内容转变成一列了,系统当然不知道应该叫什么,
# 所以我们这里要给新出现的列命名,这里为了方便后面分析使用,
# 直接给所有列重命名成英文
df3.columns = ['primary_area', 'sub_area', 'sales_man',
'product_specifications', 'month', 'target']
# 那么为什么要生成df1,2,3呢? 这是为了覆盖原数据,防止我们误操作了没法复原
再来看看,每次变更后的数据是怎么样的:
# 设置多项索引后
In: df1
Out:
1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
一级大区 二级区域 业务员 型号
南区 浙南区域 name1 type1 222.392385 110.469420 207.566226 208.341450 234.989775 244.680075 239.834925 249.525225 205.918875 276.17355 296.52318 290.709
type2 52.166115 25.912580 48.688374 48.870217 55.121058 57.394092 56.257575 58.530608 48.301958 64.78145 69.55482 68.191
name2 type1 866.394630 430.365960 808.634988 811.655100 915.471450 953.222850 934.347150 972.098550 802.217250 1075.91490 1155.19284 1132.542
type2 203.228370 100.950040 189.679812 190.388233 214.740217 223.595483 219.167850 228.023117 188.174417 252.37510 270.97116 265.658
name3 type1 1280.382795 636.007140 1195.023942 1199.487150 1352.909925 1408.700025 1380.804975 1436.595075 1185.539625 1590.01785 1707.17706 1673.703
type2 300.336705 149.186860 280.314258 281.361183 317.349242 330.435808 323.892525 336.979092 278.089542 372.96715 400.44894 392.597
name4 type1 891.738315 442.954980 832.289094 835.397550 942.250725 981.106425 961.678575 1000.534275 825.683625 1107.38745 1188.98442 1165.671
type2 209.173185 103.903020 195.228306 195.957450 221.021775 230.136075 225.578925 234.693225 193.678875 259.75755 278.89758 273.429
浙北区域 name5 type1 644.436000 320.112000 601.473600 603.720000 680.940000 709.020000 694.980000 723.060000 596.700000 800.28000 859.24800 842.400
type2 151.164000 75.088000 141.086400 141.613333 159.726667 166.313333 163.020000 169.606667 139.966667 187.72000 201.55200 197.600
name6 type1 619.650000 307.800000 578.340000 580.500000 654.750000 681.750000 668.250000 695.250000 573.750000 769.50000 826.20000 810.000
# 改成堆叠样式后
In:df2
Out:
一级大区 二级区域 业务员 型号
南区 浙南区域 name1 type1 1月 222.392385
2月 110.469420
3月 207.566226
4月 208.341450
5月 234.989775
6月 244.680075
7月 239.834925
8月 249.525225
9月 205.918875
10月 276.173550
11月 296.523180
12月 290.709000
type2 1月 52.166115
2月 25.912580
3月 48.688374
4月 48.870217
5月 55.121058
6月 57.394092
7月 56.257575
8月 58.530608
9月 48.301958
10月 64.781450
11月 69.554820
12月 68.191000
name2 type1 1月 866.394630
2月 430.365960
有点像是大括号括起来的效果。不过这里可以看到月份和销售额是没有列名的。
# 这里为了演示,又重新建了一个df,
# 因为前面df3已经重命名列名了
In: df4 = df2.reset_index()
df4
Out:
一级大区 二级区域 业务员 型号 level_4 0
0 南区 浙南区域 name1 type1 1月 222.392385
1 南区 浙南区域 name1 type1 2月 110.469420
2 南区 浙南区域 name1 type1 3月 207.566226
3 南区 浙南区域 name1 type1 4月 208.341450
4 南区 浙南区域 name1 type1 5月 234.989775
5 南区 浙南区域 name1 type1 6月 244.680075
6 南区 浙南区域 name1 type1 7月 239.834925
7 南区 浙南区域 name1 type1 8月 249.525225
8 南区 浙南区域 name1 type1 9月 205.918875
9 南区 浙南区域 name1 type1 10月 276.173550
10 南区 浙南区域 name1 type1 11月 296.523180
11 南区 浙南区域 name1 type1 12月 290.709000
可以看到,前面的一级大区,二级区域这些内容被填充上内容了。但是月份和销售额还是没有列名。
In: df4.columns = ['primary_area', 'sub_area', 'sales_man',
'product_specifications', 'month', 'target']
df4
Out:
primary_area sub_area sales_man product_specifications month target
0 南区 浙南区域 name1 type1 1月 222.392385
1 南区 浙南区域 name1 type1 2月 110.469420
2 南区 浙南区域 name1 type1 3月 207.566226
3 南区 浙南区域 name1 type1 4月 208.341450
这样就完成了一个多项索引的二维表到一维表的转换。可以看到使用pandas方便快捷,最关键的是能处理excel不太方便的地方。
后记
到这里,今天的内容已经完结了,可能还有朋友说,你标题不是说的要讲一维表和二维表相互转换吗?怎么只讲了二维表到一维表?其实一维表到二维表是最简单的内容,在excel里主要涉及到就是透视表,而pandas也提供了类似透视表的功能, 那就是pivot_table
函数。这个就可以留给朋友们自己去研究了。如果有需要可以关注公众号留言给我,我们在一篇文章里再讲讲。