前端与数据归一化

其实无论前端还是后端,在非常多场景下你都会遇到类似于这样的一个实现:
15536054800140.jpg

假定最大值为 100% 高度,我们怎么样把值映射成一个图表的形式,从数学的角度来说,我们很容易想到,这就是把 [a, b] 映射到 [0, 1] 的过程。当然,a 不一定是 0,有可能是 [0.2, 1],这是由具体需求来决定的,方法都一样。

先从简单的数学题开始吧,我们经常会使用 Math.random() 得到一个 [0, 1) 的值,然后扩大 x 倍,取整,得到了 [0, x) 的值,最后加上 offset,就得到了 [a, x + a) 的值。

那么,逆序的,我们就能得到 [a, b] -> [0, 1] 的第一种方法:如果 x 在 [a, b] 间,那么(x-a)/(b-a) 就是其在区间 [0, 1] 中得到的点,我们把这个过程叫做归一化

当然,在上文中有一点其实是欠考虑的,当 b=a 时怎么办呢?

这里有两种处理方法,一种是数学的角度,当 b=a 时,那么我们默认返回 1(100%),第二种方法是使用一个魔数,保证他们俩永远不相等(比如加一个无限小的数字)。

仔细想想,这不就是一条 y=ax+b 嘛?

15536073045598.jpg

y=ax+b 是线性关系,那么我们很容易想到,如果有极值该怎么处理。

实际上在数据中我们经常会遇到有极大值或者极小值的情况,很明显如果还是线性的,那么就不合理了,或者说肉眼来看并不是那么的舒服。

从上面函数图像的角度我们可以想到,那样找个 x 在任意值范围,只要找到对应的函数图像就行了:

15536078082041.jpg
15536078390472.jpg
这是一张如上函数的函数图像,它经过点(1, 0) 和 (100, 1),也就是说经过这个图像的转换,就可以把 [1, 100] 的内容映射在 [0, 1] 中,那么同理,我们可以得出 y=log10(x)/log10(a) 可以将 [1 - a] 的内容映射到 [0, 1],这样,你大概就可以知道 [a, b] 的内容怎么映射到 [0, 1] 了吧。

同理的,通过 arctan 的函数图像,我们也可以处理一些极值问题:arctan(x) * 2 / π

15536084402454.jpg

从函数图像上我们就可以看出,它简直是天生的归一化函数,值随着变化会无限趋近于 1。

既然有了 [0, 1) 的结果,那么相信你也会处理 [a, b) 的结果了。(如果还不会,那么回去看看我们对于 Math.random 的处理公式吧)

总结

通过对数据的处理,我们总算可以手写一个百分比柱形图了!

三张函数图像分别使用:Wolfram,Grapher 和 Google 绘制。

参考资料

如果您觉得文章不错,可以通过赞助支持我

标签: 数学

已有 2 条评论

  1. 如此好文章一定要留下名啊

  2. 这是什么数据。。。看不懂

添加新评论