精读《什么是 LOD 表达式》

LOD 表达式在数据分析领域很常用,其全称为 Level Of Detail,即详细级别。

精读

什么是详细级别,为什么需要 LOD?你一定会有这个问题,我们来一步步解答。

什么是详细级别

可以尝试这么发问:你这个数据有多详细?

得到的回答可能是:

  1. 数据是汇总的,抱歉看不到细节,不过如果您正好要看总销量的话,这儿都给您汇总好了。。

  2. 详细?这直接就是原始表数据,30 亿条,这够详细了吧?如果觉得还不够详细,那只好把业务过程再拆分一下重新埋点了。

详细程度越高,数据量越大,详细程度越低,数据就越少,就越是汇总的数据。

人很难在详细程度很高的 30 亿条记录里看到有价值的信息,所以数据分析的过程也可以看作是 对数据汇总计算的过程,这背后数据详细程度在逐渐降低

BI 工具的详细级别

如果没有 LOD 表达式,一个 BI 查询的详细程度是完全固定的:

  • 如果表格拖入度量,没有维度,那就是最高详细级别,因为最终只会汇总出一条记录。

  • 如果折线图拖入维度,那结果就是根据这个维度内分别聚合度量,数据更详细了,详细粒度为当前维度,比如日期。

如果我们要更详细的数据,就需要在维度上拖入更多字段,直到达到最详细的明细表级别的粒度。然而同一个查询不可能包含不同详细粒度,因为详细粒度由维度组合决定,不可改变,比如下面表格的例子:

行:国家 省 城市
列:GDP

这个例子中,详细级别限定在了城市这一级汇总,城市下更细粒度的数据就看不到了,每一条数据都是城市粒度的,我们不可能让查询结果里出现按照国家汇总的 GDP,或者看到更详细粒度的每月 GDP 信息,更不可能让城市粒度的 GDP 与国家粒度 GDP 在一起做计算,算出城市 GDP 在国家中占比。

但是,类似上面例子的需求是很多的,而且很常见,BI 工具必须想出一种解法,因此诞生了 LOD:LOD 就是一种表达式,允许我们在一个查询中描述不同的详细粒度

从表达式计算来看详细级别

表达式计算必须限定在同样的详细粒度,这是铁律,为什么呢?

试想一下下面两张不同详细粒度的表:

总销售额

10000

各城市销售额

北京 3000
上海 7000

如果我们想在各城市销售额中,计算贡献占比,那么就要写出 [各城市销售额] / [总销售额] 的计算公式,但显然这是不可能的,因为前者有两条数据,后者只有一条数据,根本无法计算。

我们能做的一定是数据行数相同,那么无论是 IF ELSE、CASE WHEN,还是加减乘除都可以按照行粒度进行了。

LOD 给了我们跨详细粒度计算的能力,其本质还是将数据详细粒度统一,但我们可以让某列数据来自于一个完全不同详细级别的计算:

城市 销售额 总销售额
北京 3000  10000
上海 7000  10000

如图表,LOD 可以把数据加工成这样,即虽然总销售额与城市详细粒度不同,但还是添加到了每一行的末尾,这样就可以进行计算了。

因此 LOD 可以按照任意详细级别进行计算,将最终产出 “贴合” 到当前查询的详细级别中。

LOD 表达式分为三种能力,分别是 FIXED、INCLUDE、EXCLUDE。

FIXED

{ fixed [省份] : sum([GDP]) }

按照城市这个固定详细粒度,计算每个省份的 DGP,最后合并到当前详细粒度里。

假如现在的查询粒度是省份、城市,那么 LOD 字段的添加逻辑如下图所示:

928b13cb3d0778ebfed8b4dccf6f0253.png

可见,本质是两个不同 sql 查询后 join 的结果,内部的 sum 表示在 FIXED 表达式内的聚合方式,外部的 sum 表示,如果 FIXED 详细级别比当前视图详细级别低,应该如何聚合。在这个例子中,FIXED 详细级别较高,所以 sum 不起作用,换成 avg 效果也相同,因为合并详细级别是,是一对多关系,只有合并时多对一关系才需要聚合。

最外层聚合方式一般在 INCLUDE 表达式中发挥作用。

EXCLUDE

{ exclude [城市] : sum([GDP]) }

在当前查询粒度中,排除城市这个粒度后计算 GDP,最后合并到当前详细粒度中。

假如现在的查询粒度是省份、城市、季节,那么 LOD 字段的添加逻辑如下图所示:

1d7e718fdcb6da53e891afb8d0704bdd.png

如图所示,EXCLUDE 在当前视图详细级别的基础上,排除一些维度,所得到的详细级别一定会更高。

INCLUDE

{ include [城乡] : avg([GDP]) }

在当前查询粒度中,额外加上城乡这个粒度后计算 GDP,最后合并到当前详细粒度中。

这类的例子比较难理解,且在 sum 情况下一般无实际意义,因为计算结果不会有差异,必须在类似 avg 场景下才有意义,我们还是结合下图来看:

862a62698b91ea118014d6b90cd54da4.png

这就是 avg 算不准的问题,即不同详细级别计算的平均值是不同的,但 sum、count 等不会随着详细级别变化而影响计算结果,所以当涉及到 avg 计算时,可以通过 INCLUDE 表达式指定计算的详细级别,以保证数据口径准确性。

LOD 字段怎么用

除了上面的例子中,直接查出来展示给用户外,LOD 字段更常用的是作为中间计算过程,比如计算省份 GDP 占在国内占比。因为 LOD 已经将不同详细粒度计算结果合并到了当前的详细粒度里,所以如下的计算表达式:

sum([GDP]) / sum({ fixed [国家] : sum([GDP]) })

看似是跨详细粒度计算,其实没有,实际计算时还是一行一行来算的,后面的 LOD 表达式只是在逻辑上按照指定的详细粒度计算,但最终会保持与当前视图详细粒度一致,因此可以参与计算。

我们后面会继续解读 tableau 整理的 Top 15 LOD 表达式业务场景,更深入的理解 LOD 表达式。

总结

LOD 表达式让你轻松创建 “脱离” 当前视图详细级别的计算字段。

或许你会疑惑,为什么不主动改变当前视图详细级别来实现同样的效果?比如新增或减少一个维度。

原因是,LOD 往往用于跨详细级别的计算,比如算部分相对总体的占比,计算当条记录是否为用户首单等等,更多的场景会在下次精读中解读。

讨论地址是:精读《什么是 LOD 表达式》· Issue #365 · dt-fe/weekly

如果你想参与讨论,请 点击这里,每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。

关注 前端精读微信公众号

baf9eb942720c5cdd3ba4951b7377541.png

版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证)

06-22
### 得物技术栈及开发者文档分析 得物作为一家专注于潮流商品的电商平台,其技术栈和开发者文档主要围绕电商平台的核心需求展开。以下是对得物技术栈及相关开发资源的详细解析: #### 1. 技术栈概述 得物的技术栈通常会涵盖前端、后端、移动应用开发以及大数据处理等多个领域。以下是可能涉及的主要技术栈[^3]: - **前端开发**: 前端技术栈可能包括现代框架如 React 或 Vue.js,用于构建高效、响应式的用户界面。此外,还会使用 Webpack 等工具进行模块化打包和优化。 - **后端开发**: 后端技术栈可能采用 Java Spring Boot 或 Node.js,以支持高并发和分布式架构。数据库方面,MySQL 和 Redis 是常见的选择,分别用于关系型数据存储和缓存管理。 - **移动应用开发**: 得物的移动应用开发可能基于原生技术(如 Swift/Kotlin)或跨平台框架(如 Flutter)。这有助于确保移动端应用的性能和用户体验一致性。 - **大数据云计算**: 在大数据处理方面,得物可能会使用 Hadoop 或 Spark 进行数据挖掘和分析。同时,依托云服务提供商(如阿里云或腾讯云),实现弹性扩展和资源优化。 #### 2. 开发者文档分析 类似于引用中提到的 Adobe 开发者文档模板[^2],得物也可能提供一套完整的开发者文档体系,以支持内部团队协作和外部开发者接入。以下是开发者文档可能包含的内容: - **API 文档**: 提供 RESTful API 或 GraphQL 的详细说明,帮助开发者快速集成得物的功能模块,例如商品搜索、订单管理等。 - **SDK 集成指南**: 针对不同平台(如 iOS、Android 或 Web)提供 SDK 下载和集成教程,简化第三方应用的开发流程。 - **技术博客**: 分享得物在技术实践中的经验成果,例如如何优化图片加载速度、提升应用性能等。 - **开源项目**: 得物可能将部分技术成果开源,供社区开发者学习和贡献。这不仅有助于提升品牌形象,还能吸引更多优秀人才加入。 #### 3. 示例代码 以下是一个简单的示例代码,展示如何通过 RESTful API 调用得物的商品搜索功能(假设接口已存在): ```python import requests def search_items(keyword, page=1): url = "https://api.dewu.com/v1/items/search" headers = { "Authorization": "Bearer YOUR_ACCESS_TOKEN", "Content-Type": "application/json" } params = { "keyword": keyword, "page": page, "size": 10 } response = requests.get(url, headers=headers, params=params) if response.status_code == 200: return response.json() else: return {"error": "Failed to fetch data"} # 调用示例 result = search_items("Air Jordan", page=1) print(result) ``` 此代码片段展示了如何通过 Python 请求得物的 API,并获取指定关键词的商品列表。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值