熊猫-在多个时间序列的组内插值/插补缺失值

时间:2019-10-08 10:35:09

标签: python-3.x pandas time-series interpolation imputation

我正在使用一个包含有关多个用户的每月信息的数据集。每个用户都有不同的时间范围。每个用户也缺少数据。我想做的是根据每个用户的时间范围(从最小时间到以月为单位的最大时间)填写每个用户的缺失数据。

由于数据模式属于时间序列,因此线性插值将没有意义。我还基于“用户”和“日期”为数据框设置了多索引,但是基于“时间”的插值不起作用(因为尚未实现)

x = pd.DataFrame({'user': ['a','a','a','a','a','a','a','a','b','b','b','b','b','b','b','b','b','c','c','c','c','c','c','c','c'],'dt':['2015-01-01','2015-02-01','2015-03-01','2015-04-01','2015-05-01','2015-06-01','2015-07-01','2015-08-01','2016-01-01','2016-02-01','2016-03-01','2016-04-01','2016-05-01','2016-06-01','2016-07-01','2016-08-01','2016-09-01','2017-01-01','2017-02-01','2017-03-01','2017-04-01','2017-05-01','2017-06-01','2017-07-01','2017-08-01'], 'val': [1,33,np.nan,1,np.nan,4,2,np.nan,66,2,5,1,np.nan,np.nan,7,5,np.nan,1,np.nan,7,4,np.nan,5,3,np.nan]})

user         dt     val
0     a 2015-01-01    1
1     a 2015-02-01   33
2     a 2015-03-01  NaN
3     a 2015-04-01    1
4     a 2015-05-01  NaN
5     a 2015-06-01    4
6     a 2015-07-01    2
7     a 2015-08-01  NaN
8     b 2016-01-01   66
9     b 2016-02-01    2
10    b 2016-03-01    5
11    b 2016-04-01    1
12    b 2016-05-01  NaN
13    b 2016-06-01  NaN
14    b 2016-07-01    7
15    b 2016-08-01    5
16    b 2016-09-01  NaN
17    c 2017-01-01    1
18    c 2017-02-01  NaN
19    c 2017-03-01    7
20    c 2017-04-01    4
21    c 2017-05-01  NaN
22    c 2017-06-01    5
23    c 2017-07-01    3
24    c 2017-08-01  NaN

在上面的数据集中,“ val”列缺少几个值,我正在研究如何为多个“用户”自动执行此过程。

如果没有,将为每个用户建立一个时间序列模型是有意义的。每个用户的数据点数?

任何输入/解决方法将不胜感激。

谢谢, 卢克。

2 个答案:

答案 0 :(得分:0)

您可以使用Groupby + apply来填写缺失的值,具体取决于用户。无需为每个用户创建系列。

以下是如何填写此缺失数据的示例( 除了这些方法,您还可以创建自己的函数):

1。使用interpolate对每个组进行插值。使用fillna 填充

x['val']=x.groupby('user')['val'].apply(lambda x: x.fillna(x.interpolate()))
print(x)

   user          dt   val
0     a  2015-01-01   1.0
1     a  2015-02-01  33.0
2     a  2015-03-01  17.0
3     a  2015-04-01   1.0
4     a  2015-05-01   2.5
5     a  2015-06-01   4.0
6     a  2015-07-01   2.0
7     a  2015-08-01   2.0
8     b  2016-01-01  66.0
9     b  2016-02-01   2.0
10    b  2016-03-01   5.0
11    b  2016-04-01   1.0
12    b  2016-05-01   3.0
13    b  2016-06-01   5.0
14    b  2016-07-01   7.0
15    b  2016-08-01   5.0
16    b  2016-09-01   5.0
17    c  2017-01-01   1.0
18    c  2017-02-01   4.0
19    c  2017-03-01   7.0
20    c  2017-04-01   4.0
21    c  2017-05-01   4.5
22    c  2017-06-01   5.0
23    c  2017-07-01   3.0
24    c  2017-08-01   3.0

2。 ffill方法:

x['val']=x.groupby('user')['val'].apply(lambda x: x.ffill())

   user          dt   val
0     a  2015-01-01   1.0
1     a  2015-02-01  33.0
2     a  2015-03-01  33.0
3     a  2015-04-01   1.0
4     a  2015-05-01   1.0
5     a  2015-06-01   4.0
6     a  2015-07-01   2.0
7     a  2015-08-01   2.0
8     b  2016-01-01  66.0
9     b  2016-02-01   2.0
10    b  2016-03-01   5.0
11    b  2016-04-01   1.0
12    b  2016-05-01   1.0
13    b  2016-06-01   1.0
14    b  2016-07-01   7.0
15    b  2016-08-01   5.0
16    b  2016-09-01   5.0
17    c  2017-01-01   1.0
18    c  2017-02-01   1.0
19    c  2017-03-01   7.0
20    c  2017-04-01   4.0
21    c  2017-05-01   4.0
22    c  2017-06-01   5.0
23    c  2017-07-01   3.0
24    c  2017-08-01   3.0

3。使用组的mean。填写fillna

x['val']=x.groupby('user')['val'].apply(lambda x: x.fillna(x.mean()))
print(x)

   user          dt        val
0     a  2015-01-01   1.000000
1     a  2015-02-01  33.000000
2     a  2015-03-01   8.200000
3     a  2015-04-01   1.000000
4     a  2015-05-01   8.200000
5     a  2015-06-01   4.000000
6     a  2015-07-01   2.000000
7     a  2015-08-01   8.200000
8     b  2016-01-01  66.000000
9     b  2016-02-01   2.000000
10    b  2016-03-01   5.000000
11    b  2016-04-01   1.000000
12    b  2016-05-01  14.333333
13    b  2016-06-01  14.333333
14    b  2016-07-01   7.000000
15    b  2016-08-01   5.000000
16    b  2016-09-01  14.333333
17    c  2017-01-01   1.000000
18    c  2017-02-01   4.000000
19    c  2017-03-01   7.000000
20    c  2017-04-01   4.000000
21    c  2017-05-01   4.000000
22    c  2017-06-01   5.000000
23    c  2017-07-01   3.000000
24    c  2017-08-01   4.000000

答案 1 :(得分:0)

这就是我会做的。

假设是您知道如何推断缺失值。

然后,我将创建用于插补数据的函数,应该是这样的:

def f(x):
    # x is a DataFrame with columns [datetime, value]
    # ...
    # ...
    output = ...
    # output is a dataframe with columns [datetime, value],
    # where value is a column with the data imputed (so without nans)
    return output

然后您可以做:

x.groupby(user).apply(f)