通过pandas melt和pandas pivot快速进行时间序列的插补
- 2020 年 12 月 16 日
- AI
电商销量预测中,数据的处理一直是一个恶心的问题,因为我们拿到的常常是层次不齐的销量数据,举个例子:
北京:销量数据 2017-01-01~2020-11-11
某个二线城市:销量数据 2018-01-01~2020-10-11
某个n线城市:销量数据 2019-12-01~2020-05-01
这是很常见的数据场景,而建模的时候,一般来说我们会对所有城市的数据进行时间的对齐,如果引入了sku层面,甚至要对每个城市的所有的sku进行时间的对齐,仅仅以一个城市为例:
北京:
鞋子:销量数据 2018-01-02~2020-11~11
衣服:销量数据 2019-08-02~2020-03-05
袜子:销量数据 2020-01-01~2020-10-01
这个时候就涉及到了周期的插补,常见的插补就是没有销量记录的样本其销量用0来进行插补或者直接就先用nan代替。恶心的地方在于这个时间周期统一的过程。下面以m5的数据集作为例子:
M5的数据非常标准,每一个州,每一个商店,每一个品类下的每一个商品都统一成了长度为1919的序列数据,下面我们删掉一些记录从而符合真实的业务下的原始数据:

这个是m5的原始数据先做了一些转换得到的,这个形式更复合业务上的形式,例如常见的电商销量预测里,按照city shop sku date sales,即城市 商店id sku的id 日期 销量这样来排列,m5的原始数据经过主办方的一次加工了,所有的sku的长度都是 1919,下面为了贴近一点实际的脏数据的情况,我们删掉前面几条:

这里我们删除了id为第一个的sku的前五条记录,这样就出现了业务中常常遇到的 每一个sku的序列数据长度不同的情况。
然后我们使用pivot进行展开:

可以看到,pivot展开之后,将序列数据从纵向存储转化为了横向展开,横向展开的长度以最长的一条序列数据为准,例如这里的序列数据最长是1919,因此展开之后的维度增加了1919维,可以注意到,被我们删除的第一个样本,被删除的部分自动进行了缺失值nan的填充使得所有样本的长度全部相同。
然后我们再通过melt,把行转列

这样就进行了自动的等长处理了,非常的方便;
如果pandas性能是瓶颈,可以考虑多核计算的modin或者是分布式dask,pyspark dataframe也有相应接口。
补充:pandas的不同版本的pivot的功能有一些差异,并且有的版本是pivot_table的接口,需要注意,目前使用的版本是pandas1.12,在windows下使用pivot莫得问题,但是在linux下却要使用pivot_table,否则会出现报错的问题