在拿到一张投入产出表的时候,很多人的第一反应是"这表我好像在哪见过,但接下来该算什么来着"。尤其当手里的任务变成"用Excel算直接消耗系数和完全消耗系数"时,真正卡住的往往不是经济学概念,而是:公式到底该往哪个单元格里填、行列是谁除以谁、为什么算出来的结果跟教材对不上。
这篇东西就是把这件事彻底讲透。我会用一张自洽的三部门投入产出表,从原始数据一直推到直接消耗系数和完全消耗系数,每一步的Excel操作、每一个容易犯的方向性错误、以及最后怎么验证结果,都会拆开讲。适合刚接触投入产出分析的学生、做产业关联研究的研究人员,以及需要在Excel里快速完成系数测算的职场人。
1. 先从表的结构说起:中间投入、最终使用与总产出是怎么咬合在一起的
1.1 一张投入产出表的三象限结构
投入产出表最核心的骨架,是一张三部门表就能说明白的。假设我们把整个经济体简化成农业、工业、服务业三个部门,那么一张最基础的竞争型投入产出表长这样:
| 部门 | 农业(中间投入) | 工业(中间投入) | 服务业(中间投入) | 最终使用 | 总产出 |
|---|---|---|---|---|---|
| 农业 | 30 | 60 | 10 | 50 | 150 |
| 工业 | 40 | 120 | 40 | 100 | 300 |
| 服务业 | 20 | 40 | 30 | 60 | 150 |
| 增加值 | 60 | 80 | 70 | - | - |
| 总投入 | 150 | 300 | 150 | - | - |
这张表很“小”,但结构并不小。左上角那个3×3的方块叫第Ⅰ象限,也叫中间投入矩阵,里面每个数字x_ij的含义是“生产部门j那一个部门的产品时,消耗了多少部门i的产品”。比如第1行第2列的那个60,意思就是工业部门在生产过程中,消耗了60亿元的农产品。第Ⅱ象限是最终使用,包含了消费、资本形成、出口等去向,它和中间投入合在一起,构成了每个部门总产出的完整去向。
还有第Ⅲ象限,一般放在列的方向下方,就是增加值。增加值包含劳动者报酬、生产税净额、固定资产折旧和营业盈余。增加值那一列数字的价值在于,它保证了表在列的方向上也有一个平衡:中间投入合计+增加值=总投入。
1.2 行平衡与列平衡:算系数之前必须先相信这张表是自洽的
为什么要先讲平衡?因为投入产出表里的所有系数计算,都建立在行平衡和列平衡之上。
行平衡说的是:中间投入合计+最终使用=总产出。以农业为例,农业行中间投入合计是30+40+20=90,最终使用是50,两者之和正好等于总产出150。列平衡说的是:中间投入合计+增加值=总投入。农业列中间投入合计是30+60+10=100,增加值是60,相加正好等于总投入150。
“总投入”和“总产出”在投入产出表里数值必然相等,因为同一个部门的产出量和投入量就是同一件事的两面。后续计算直接消耗系数时,我们用的分母就是这个总投入(等价于总产出)。这一条很多初学者忽略了,结果拿着总产出那一行当分母,算出来的系数其实也没错,但心里不明白为什么可以用行上的数去除列上的数。原理就是:行总和列总在同一张表里必须相等。
所以拿到任何一张投入产出表,第一件事不是急着算系数,而是先核对平衡关系。如果行不平衡或者列不平衡,后面所有系数都是空中楼阁。
1.3 直接消耗系数和完全消耗系数,各自回答什么问题
直接消耗系数a_ij的定义是:生产1单位j部门产品,直接消耗多少i部门产品。它回答的是一个最直观的生产技术问题——“我产出一块钱的工业品,当场要吃掉多少农产品”。
完全消耗系数b_ij回答的问题则深一层:生产1单位j部门产品,算上所有直接和间接消耗,总共需要多少i部门产品。这里多出来的“间接消耗”,是产业链传导出来的。工业产出的过程中要耗电,发电的过程要耗煤,采煤的过程要用到化工产品,化工产品的生产又可能消耗农产品……这种一层层嵌套的关系,是直接消耗系数表单靠看数字看不出来的。
清楚了这两个系数在回答什么问题,后面Excel怎么操作都不会跑偏。
2. 直接消耗系数:其实就是“每个格子除以所在列的总投入”
2.1 计算公式与Excel里的行列对应关系
直接消耗系数的公式是:
a_ij = x_ij / X_j
其中x_ij就是中间投入矩阵第i行第j列的那个数,X_j是j部门的总投入。这里最关键也最容易翻车的地方在于:分母是“所在列的总投入”,而不是“所在行的总产出”。
为什么是列?因为从列的方向看,中间投入+增加值=总投入,一列代表的是一个生产部门完整的投入结构。我们要算的是“生产每1单位j产品要消耗多少i产品”,分母当然就应该是j产品的总生产规模,也就是j列的总投入。
在Excel里的对应关系也很直观。打开原始表之后,如果中间投入矩阵放在B2:D4区域,总投入(总产出)那一行放在B6:D6,那么B2单元格里的公式就是:
=B2/B$6
这里为什么要对6前面加美元符号?因为向右填充时,列标B会变成C、D,对应的总投入单元格也要跟着变;但向下填充时,每一行的分子都在变,分母却始终锁定在第6行。所以需要在行号前面加$。如果忘了加,往下拖两行,分母就会跑到总产出下面那个空单元格里,算出来的结果全是#DIV/0!。
2.2 实操:一次填充生成整张直接消耗系数表
我建议新建一个工作表,命名为“系数计算”,把原始表的数据引用过来,然后单独留一块区域放直接消耗系数矩阵。
假设在“系数计算”表里:
- B2:D4放直接消耗系数矩阵区域
- 原始表在名为“原始表”的工作表,中间投入矩阵是'原始表'!B2:D4,总投入行是'原始表'!B6:D6
那么在'系数计算'!B2单元格输入:
='原始表'!B2/'原始表'!B$6
然后向右填充到D2,再向下填充到D4,这张3×3的直接消耗系数表就出来了。理论上讲,直接消耗系数运算是逐元素除法,不是数组乘法,所以不需要Ctrl+Shift+Enter,普通填充就行。
算完以后,你这张表里的数值应该是下面这个样子:
| 部门 | 农业 | 工业 | 服务业 |
|---|---|---|---|
| 农业 | 0.200 | 0.200 | 0.067 |
| 工业 | 0.267 | 0.400 | 0.267 |
| 服务业 | 0.133 | 0.133 | 0.200 |
验证一下:30/150=0.2,60/300=0.2,10/150≈0.0667。全部对得上。
2.3 一个不用背就能记住的检查规则:每列之和必须小于1
直接消耗系数表算完之后,不要急着进行下一步,先看每一列的列合计。
专业点讲,每列列合计反映的是“生产1单位产品,所有中间投入合计占总投入的比例”。因为列平衡关系里还有一块增加值,增加值占总投入的比例必然大于0,所以中间投入的合计比例必然小于1。
换句话说:直接消耗系数每一列的和都必须严格小于1。如果某列求和等于1甚至超过1,说明这张表的经济含义已经崩坏了——生产一块钱产品,把所有中间投入加起来就要吃掉一块钱甚至更多,那增加值还从哪儿来?
我实操中见过不少新手把行方向的数据错当成列,算出来的“系数表”行和全等于1,列和乱七八糟。用“每列和<1”这条规则一卡,立刻就能发现问题。以前我们手动算的时候,这条规则是重要验算手段;现在用Excel,你也可以在每个系数表下方加一行=SUM(B2:B4),专门盯这个值。
3. 完全消耗系数:矩阵求逆在Excel里其实被MINVERSE封装好了
3.1 完全消耗为什么不能用“直接相加”解决
很多人刚接触完全消耗系数时,第一反应是:既然完全消耗=直接消耗+间接消耗,那我把直接消耗系数加起来不就行了?答案是不行。
原因是间接消耗是无穷多层的。以我们这张表为例,工业每生产1单位产品,直接消耗农业0.2。但工业还直接消耗工业自身0.4,这0.4单位的工业品在生产时,又需要消耗农业品0.2×0.4=0.08。然后这0.08单位的工业品再生产,又需要消耗更少的农业品……这么一层层追下去,把无穷多轮的间接消耗全部加起来,才是真正的完全消耗。
这个无穷相加在数学上可以收敛成一个简洁的表达式。把直接消耗系数矩阵记为A,那么考虑I+A+A²+A³+…这个矩阵级数,其中A²表示两轮间接的消耗,A³表示三轮间接的消耗,依此类推。由于直接消耗系数每列和小于1(这是第2节那条检查规则的深层意义),这个级数是收敛的,而且它的极限是(I-A)^(-1),也就是列昂惕夫逆矩阵。
列昂惕夫逆矩阵还有一个名字叫完全需要系数矩阵,它表示“最终需求增加1单位时,各部门需要提供的总产出”。这个矩阵的对角元通常大于1,因为它把本部门在循环中重复出现的部分也算进去了。而完全消耗系数是与它相差一个单位矩阵的关系:
完全消耗系数B = (I-A)^(-1) - I
所以Excel里的计算路线就非常清晰了:先根据直接消耗系数A构造I-A矩阵,再求逆,最后减掉单位矩阵I。
3.2 单位矩阵的构造与I-A矩阵的建立
在Excel里构造一个3×3的单位矩阵,最土但最稳的方法是直接填:对角线上填1,其他位置填0。3×3规模不大,手动填几秒钟就完事。如果是42部门甚至更多部门的大表,手动填就不现实了,这时可以用一个IF公式,比如在某个区域左上角单元格输入:
=IF(ROW()-1=COLUMN()-1,1,0)
然后选中整个n×n区域按Ctrl+Shift+Enter批量生成。这个公式的原理是:当单元格所在行号减1等于列号减1时,也就是落在主对角线上时,返回1,否则返回0。注意里面的“减1”要根据区域起始行列号调整,只要保证相对偏移相等就行。
有了A矩阵和单位矩阵I,构造I-A就是纯粹的逐元素减法。你可以直接在I-A区域的每个单元格输入=I单元格-A单元格,一个个引用;也可以一次性选中对应大小的区域,输入=单位矩阵区域-系数矩阵区域,然后按Ctrl+Shift+Enter,让整个区域同时得到结果。对于3×3的例子,我建议用前一种逐格引用的方式,因为每一步都看得见、查得着;大表可以偷懒用后一种数组公式。
以我们的数据为例,I-A矩阵是:
| 部门 | 农业 | 工业 | 服务业 |
|---|---|---|---|
| 农业 | 0.800 | -0.200 | -0.067 |
| 工业 | -0.267 | 0.600 | -0.267 |
| 服务业 | -0.133 | -0.133 | 0.800 |
注意这里对角线是“1减去直接消耗系数”,非对角线是“0减去直接消耗系数”,所以是负号。很多人在这一步看到负数会心里一慌,怀疑是不是算错了。没有,负号完全正常,因为把等式(I-A)X=Y展开后,非对角线上的那些项都带负号。
3.3 MINVERSE、MMULT与Ctrl+Shift+Enter
求矩阵逆矩阵,Excel提供了一个现成函数MINVERSE。它和普通的函数不太一样:普通函数返回一个单独的值,而MINVERSE返回一个数组,所以必须以数组公式的形式输入。
具体操作是:先选中一个与矩阵同样大小的空白区域。比如I-A矩阵在F6:H8区域,那么就在旁边选中一个3×3空白区域,然后在编辑栏输入:
=MINVERSE(F6:H8)
输入完之后千万不要直接按回车,而是按住Ctrl+Shift再按Enter。按下这个组合键后,Excel会在选中区域的所有单元格里填入逆矩阵的对应元素,并且公式栏里会出现一对大括号{ },表示这是数组公式。
如果你用的是Excel 365或Excel 2021,新版的动态数组引擎允许你直接按回车,让结果自动溢出到旁边。但考虑到很多协作环境、旧版本兼容性问题,我还是建议养成按Ctrl+Shift+Enter的习惯。在别人模板里看到带花括号的公式,也不会因为不理解而手忙脚乱。
算完逆矩阵后,如果只是要验证算得对不对,就用MMULT验证乘法。比如验证(I-A)的逆矩阵真的是它的逆,应该让(I-A)×(I-A)^(-1)等于单位矩阵。方法是选中另一个3×3区域,输入:
=MMULT(F6:H8, MINVERSE的结果区域)
同样按Ctrl+Shift+Enter。如果结果是主对角线全为1、非主对角线全为0(或者因为浮点误差出现0.000000001这种极小数字),那就说明求逆没问题。
MMULT函数要求两个矩阵的维度匹配,左边矩阵的列数必须等于右边矩阵的行数。对3×3矩阵来说刚好都匹配;对大表来说,做MMULT前要仔细检查区域的大小,不然会直接返回#VALUE!错误。
3.4 完全需要系数和完全消耗系数的区别,别把结果多讲了一个“1”
这是我在实际交流中反复遇到的一个混淆点。求逆得到的(I-A)^(-1)是列昂惕夫逆矩阵,通常叫完全需要系数矩阵。把它对角线的数字直接念给业务方听,很容易造成误解,因为对角元代表的是“本部门最终需求增加1单位时,本部门总的产出需要”,其中包含了对本部门产出的第一单位“初始需求本身”。
而完全消耗系数要减去单位矩阵I,也就是把那些“初始需求”扣掉,剩下的才真正是“消耗”的部分。
仍然用我们的例子验证一下。根据前面算出来的A矩阵,求逆后的列昂惕夫逆矩阵约等于:
| 部门 | 农业 | 工业 | 服务业 |
|---|---|---|---|
| 农业 | 1.491 | 0.567 | 0.313 |
| 工业 | 0.835 | 2.117 | 0.775 |
| 服务业 | 0.388 | 0.447 | 1.431 |
那么完全消耗系数就等于这个矩阵减去单位矩阵:
| 部门 | 农业 | 工业 | 服务业 |
|---|---|---|---|
| 农业 | 0.491 | 0.567 | 0.313 |
| 工业 | 0.835 | 1.117 | 0.775 |
| 服务业 | 0.388 | 0.447 | 0.431 |
可以看到,完全消耗系数的对角元素依然可以大于1,比如工业那行第2列是1.117。很多人看到这个数字会惊一下:“一个部门怎么会消耗超过1单位的自己?”实际上完全可能。因为生产工业品要消耗电力和各种工业中间品,而这些中间品在生产时又需要工业品作为投入,所有轮次加起来,对自身的总消耗完全可以超过1。
4. 一个完整的三部门算例:从原始表到两张系数表的全过程
4.1 录入原始数据并完成平衡核对
先把原始表完整录入Excel。我习惯把表放在名为“原始表”的第一个工作表里:
- A1输入“部门”
- B1:D1输入“农业”“工业”“服务业”
- A2:A4输入“农业”“工业”“服务业”
- B2:D4填入中间投入矩阵
- A5输入“最终使用”,B5:D5填入最终使用
- A6输入“总产出”,B6:D6填入总产出
- A7输入“增加值”
- A8输入“总投入”,B8:D8填入总投入
- A9输入“列平衡检查”
在B7单元格输入=B8-SUM(B2:B4),也就是用总投入减去中间投入合计,看是否等于前面给定的增加值。这里如果填出来的结果和你预期增加值一致,说明列平衡没问题。行平衡也可以在F列加一个合计列,用SUM(B2:D2)+E2对比F2。
这个核对环节虽然看起来有点“多此一举”,但真实表格从系统里导出来时,常常会有精度问题、单位问题甚至漏行问题。早点发现,总比后面带着错误数据算完所有系数再回头找原因强。
4.2 直接消耗系数表的逐步操作
在“原始表”右侧或者新建一个“系数计算”工作表,我按下面步骤操作:
第一,在“系数计算”表的B2:D4区域生成直接消耗系数矩阵。B2输入:
='原始表'!B2/'原始表'!B$8
注意这里B$8是总投入所在行,不是总产出行。虽然两行数值一样,但逻辑上要清晰,建议用总投入行。
向右填充到D2,再向下填充到D4,得到前面展示的系数表。
第二,给系数表加一行“列合计”,在B5输入=SUM(B2:B4),向右填充。检查三列合计都小于1,并且加上增加值系数后正好等于1。举个例子,农业列合计是0.2+0.267+0.133=0.6,农业增加值系数是60/150=0.4,两者相加为1。
这一步不仅验证了正确性,还让你对这张表的产业结构有一个直观认知:农业列合计0.6,说明农业产出的60%来自中间投入,40%来自增加值;工业列合计0.733,说明工业对中间投入的依赖更强。
4.3 完全消耗系数表的逐步操作与结果核对
接下来按第3节的流程——
第一步,在“系数计算”表里找一个空白区域,比如F6:H8,生成单位矩阵。可以直接手填,也可以用IF公式生成。我建议手填快速生成3×3单位矩阵。
第二步,在J6:L8构造I-A矩阵,J6输入=F6-B2,J7输入=F7-B3,逐个引用做减法,把九个格子都填完。得到上一节展示的I-A矩阵。
第三步,选中N6:P8区域,输入=MINVERSE(J6:L8),按Ctrl+Shift+Enter,得到列昂惕夫逆矩阵。
第四步,选中R6:T8区域,输入=N6:P8-F6:H8,按Ctrl+Shift+Enter,得到完全消耗系数矩阵。
第五步,验证结果:可以选一块区域输入=MMULT(J6:L8,N6:P8),按Ctrl+Shift+Enter,如果得到近似单位矩阵,说明整个过程没有出错。再检查完全消耗系数的每个元素,理论上都应该大于等于直接消耗系数里对应位置的元素。
我自己做完这套流程后,还会特别看一眼完全消耗系数表里工业对农业的系数0.567,然后对着直接消耗系数0.2想一下:多出来的0.367全是间接消耗,可见只看直接消耗系数会低估部门之间的真实关联强度。这就是为什么产业关联分析里,完全消耗系数往往比直接消耗系数更有决策参考价值。
5. 在多部门大表上实操,我踩过的坑和一些想提醒你的事
5.1 数组公式没按Ctrl+Shift+Enter,结果全是#VALUE!
MINVERSE和MMULT这两个函数我至少见过十次因为没按组合键而报错。现象是:选区里只有第一个格有数字,其他全是#VALUE!,或者整个区域全部#VALUE!。
原因在于Excel的老版数组规则:MINVERSE期望的是一个数组上下文,如果没有按Ctrl+Shift+Enter,它只会在当前单元格尝试返回一个数组的第一个值,但因为没有数组上下文,计算就失败了。
解决方法是点击编辑栏,重新按一遍Ctrl+Shift+Enter。新版Excel 365可以按回车直接溢出,但如果你在做一些兼容性要求高的模板,我还是建议保留数组公式的习惯。另外有一个小技巧:如果你在协作中收到一份同事发来的表格,里面MINVERSE区域显示#VALUE!,第一步就检查公式栏有没有那对大括号。
5.2 MINVERSE选区大小不对,要么结果残缺要么冒出#N/A
MINVERSE要求所选区域必须和矩阵维度完全一致。3×3矩阵就选3×3区域,如果你不小心选了3×4,多出的第4列单元格会返#N/A;如果选了2×3,结果只有前两行,看起来好像“算出来了”,其实残缺。
实际大表操作时,我建议先确认矩阵区域的行列数,再用鼠标精确框选同样大小的区域,最后输入公式。为了减少这种低级失误,我还有一个习惯:在矩阵区域旁边放一个=ROWS区域和=COLUMNS区域,确认维度后再求逆。
5.3 直接消耗系数行列转置的“经典翻车”
投入产出表中矩阵的表示方式全世界并不完全统一。有些资料里直接消耗系数矩阵A的写法是横行为消耗部门、纵列为被消耗部门,跟Excel默认的“行为投入、列为产出”方向相反。如果照搬公式求逆,虽然INF函数不会报错,但算出来的完全消耗系数矩阵是原矩阵的转置,经济解读就完全错了。
判断方向的方法很简单:直接消耗系数矩阵每一列的“生产消耗别人”的视角,必须和中间投入矩阵保持一致。原始表里第Ⅰ象限的x_ij怎么排,A矩阵就怎么排。如果你习惯用行合计等于1检查,那是行方向不同;用第2节说的“每列和小于1”才对应正确的列方向。这是我反复强调这条检查规则的原因,它不止是验算,更是方向判断的依据。
5.4 用小数位偷懒导致的连锁误差
Excel里显示的小数位数和实际上存储的小数位数是两回事。如果你只保留2位小数放到I-A矩阵里,比如0.07、-0.27这种,求逆时Excel用的是你输入的实际数值,但看起来很有迷惑性,最终结果可能会和用完整精度算出来的有显著差异。
要避免这个问题,在构造I-A矩阵时不要手动“抄数字”,而是直接引用直接消耗系数单元格。比如第4节的操作里,I-A矩阵的每个单元格都用=F6-B2这种公式引用,而不是把0.8、-0.2这种数值敲进去。这样即使你设置了小数显示格式,底层计算仍然是完全精度。
5.5 从三部门扩展到42部门甚至153部门时的操作建议
官方投入产出表最常见的规模是42部门,近年还有153部门的细分表。42×42的矩阵在Excel里跑MINVERSE完全没问题,但153×153矩阵求逆会有明显的计算压力,文件也会变得很卡。这时候我再建议你考虑一下别的工具,比如用Python的NumPy做同样的运算,效率会高很多。Excel适合教学、小规模测算和快速验证,一旦进入部门特别多、需要反复调整数据的场景,还是要果断换工具。
另外,在42部门大表上操作时,纯手工一个一个引用I-A矩阵的单元格会非常痛苦。我的做法是:
- 选中与A矩阵同样大小的区域,输入=单位矩阵区域-A矩阵区域,按Ctrl+Shift+Enter一次性生成I-A矩阵。
- 然后选中同样大小的区域,输入=MINVERSE(I-A矩阵区域),按Ctrl+Shift+Enter。
- 最后选中同样大小的区域,输入=逆矩阵区域-单位矩阵区域,按Ctrl+Shift+Enter得到完全消耗系数。
整个流程只有三条数组公式,对大表来说省时省力。唯一要注意的是,数组公式区域一旦建好,想改其中某一个单元格是不允许的,Excel会提示“不能更改数组的某一部分”。要修改就只能全选整个数组区域再按Delete删除重来。这个限制对大表很烦,所以我通常会在求逆之前把所有输入数据复核一遍,确保一次性算完。
5.6 关于结果的一个实操提醒
完全消耗系数的值一般会到小数后好几倍,比如列昂惕夫逆矩阵里的2.117。在向别人汇报时,建议使用“完全需要系数”和“完全消耗系数”两个词时保持表述一致。我看到过不少报告把列昂惕夫逆矩阵直接称作“完全消耗系数矩阵”,严格讲并不准确,少了减I那一步。自己清楚这点后,再去对照文献和教材,就不会被不同的名词搞晕。
如果后续你还要做影响力系数、感应度系数,或者把投入产出表跟就业、碳排放数据结合起来分析,这整套Excel流程就是你打下的地基。数据算得准,后面的延伸分析才站得住脚。