浅谈数据分析师心路历程(内附破局思考)
晃眼间,毕业从事数分也有快半年了。初入数据分析师的这个行业(非纯互联网),也存在一段时间的适应期。刚开始会发现工作内容和想象中的互联网数据分析师有比较大的区别。工作中比较少专题分析、ab测试等印象中常见大厂数分的工作内容。实际上更多的是准确的取数、计算指标、落表、维护和定位数据异常、分析异常原因并最终修复异常。刚开始也会觉得现实与想象差距较大,不时陷入沉思。
渐渐的,我发现数据分析师工作的重点还应该在于合理地设计复用性强、业务兼容性广的指标以满足不同业务的需求,这样可以从根源上减少机械取数的繁复。这也是我近期找寻到的破局之路:优化指标灵活度,减少重复劳动,兼顾不断变化的业务需求。
给定一个场景,业务a和业务b都需要客户的负债峰值指标,但业务a需要近2年的峰值,业务b需要近3年的峰值。如果只是为了满足业务需求,给他们各自统计一变固然是个方法,但这是个效率较低的方案。如果又出来业务c、d分别需要不同年份区间的峰值呢?这时各自统计就显得重复劳动了。那么这时候就需要设计业务兼容性广的指标来尽可能地覆盖纷繁复杂的业务需求。还是讨论刚刚提及不同时间口径下负债峰值的场景。这时我们可以考虑构建一张客户维度的各年负债峰值明细表,具体表结构如下所示:
这个明细表包含客户id、负债峰值、峰值年份、峰值日期。那么当业务给定一个明确的年份(日期)范围我们都可以基于这张明细表来进行聚合汇总。具体步骤就是先选定年份(日期)范围,之后对峰值列按照客户id分组后求max。比如,我们需要得到客户2020年以来的负债峰值,通过上述限定,我们可以得到客户0001的峰值为150,客户0002的峰值为220。上面只是近期重拾工作热情的一个小细节,小例子。初入职场,作为初级数据分析师,在坚守日常工作之余,还得多思考,多想想优化方案,一步一步的就会找到突破瓶颈的方法。路还很长,任重道远。
--------------------------------------------------------------华丽分界线------------------------------------------------------------
以上分享完想法,当然少不了落地执行。其实指标在时间(年份、月份)的拓展就是数仓建模中维度分析维度下钻的基础。数仓指标维度设计得越丰富,那数仓指标的业务灵活性就越强。
那么回到上述的想法,何以构建客户层面逐年峰值表呢?其中一个最低效的方法是每天都去计算客户逐年的负债峰值,这显然是一个费时费力的方法。得到相同结果,我们可以采用更高效的办法:历史数据增量更新。具体逻辑可以参见我前面的一篇文章:
《数据业务札记05:全量结果增量覆盖》https://www.nowcoder.com/discuss/393431111362379776
简单来说,我们仅需要在任务执行的那天基于全量数据跑一边客户逐年负债峰值的结果并记录下来,作为初始历史表。之后每一天用客户当前负债结果去刷新历史表的结果即可。思路非常简单,但实际操作中我们得留意以下需要特别注意的两点:
①当前表出现新客户,该客户没有在历史表中出现。
②当前表出现新年份(比如跨年),历史表中没有新年份。
以上两点都可以采用表关联,case when更新字段的方法来得到解决。那么我们现在先在自己本地数据库建历史表、当前表来展示一下效果吧。
历史表表名为:price_max_yearly,其记录的是客户id、峰值出现的年份以及峰值数值。
当前表名为:price_new,同样记录了客户id、当前负债、当前负债出现年份。
在开工之前,我们不妨分析一下当前表和历史表之间的差异,不难发现,当前表中出现了历史表里没有出现过的客户号,此外也有出现历史表中没有出现过的年份。那么对于这种情况,我们可以使用当前表为左表,price_new left join price_max_yearly。关联条件为客户id和年份。这样的操作下,我们可以使用当前表的年份、客户号来补充历史表的内容,同时不获取历史表中历史年份峰值这些冗余信息。之后我们近需要对历史表被左关联的部分进行数据更新,之后再把更新后数据和无需更新的历史数据进行union 合并后去重即可。
具体脚本如下:
select custida,max_year,max(price_max) price_max from ( select case when custida is null and custidb is not null then custidb else custida end as custida , case when max_year is null and price_year is not null then price_year else max_year end as max_year, case when price_new>price_max or (price_new is not null and price_max is null) then price_new else price_max end as price_max from (select * from price_new) b left join (select * from price_max_yearly)a on a.custida=b.custidb and a.max_year=b.price_year union select * from price_max_yearly ) a group by custida,max_year
那么我们便可以得到更新后的历史表,结果如下:
可以看到,历史表中增加了之前没有的客户id、年份情况,历史表与当前表相同年份的数据也会被上述逻辑刷新。那么基于这张客户逐年峰值表,我们能干嘛呢?其实基于这张表我们可以解放很多生产力。这种表可以通过在外层代码套一个分组,求max得到近n年峰值、给定年份区间的峰值,也可以做各年峰值序列分析等,基于维度拓展的指标表可以更好的提高指标的业务覆盖度,提高工作效率。
以下展示一下基于上述更新后历史表计算20220101-20230101期间客户负债峰值的脚本和结果:
脚本如下:
select custida,max_year,max(price_max) price_max from ( select case when custida is null and custidb is not null then custidb else custida end as custida , case when max_year is null and price_year is not null then price_year else max_year end as max_year, case when price_new>price_max or (price_new is not null and price_max is null) then price_new else price_max end as price_max from (select * from price_new) b left join (select * from price_max_yearly)a on a.custida=b.custidb and a.max_year=b.price_year union select * from price_max_yearly ) a where max_year between 20220101 and 20230101 group by custida,max_year#数据分析师##数据分析秋招##数分##迷茫##我的求职思考#