为行组添加不同的缺失日期

时间:2019-02-20 11:42:46

标签: python pandas dataframe

让我们假设我有一个由以下几列组成的数据集:

  • Stock_id:股票编号
  • Date:日期为2018年,例如25/03/2018
  • Stock_value:该特定日期的股票价值

我有一些日期,每种股票各不相同,数据集中完全没有这些日期,我想填写它们。

由于缺少日期,我的意思是每个日期甚至没有一行;并不是说这些存在于数据集中,只是行中的Stock_value是NA等。

一个局限性是,一些股票是在2018年的某个时候引入股票市场的,因此,显然,我不想填写这些股票不存在的日期。

我的意思是,如果某股票在2018年5月21日引入市场,那么我显然想填写该股票从2018年5月21日至2018年12月31日的所有缺失日期,但是不是在21/05/2018之前的日期。

最有效的方法是什么?

我已经在StackOverflow上看到了一些帖子(post_1post_2等),但是我认为我的情况比较特殊,所以我希望看到一种有效的方法。

让我提供一个例子。让我们将其限制为两只股票,并且只限于2018年1月1日至2018年7月1日的一周,否则将不适用于此。

让我们假设我最初有以下内容:

Stock_id    Date    Stock_value
1   01/01/2018  124
1   02/01/2018  130
1   03/01/2018  136
1   05/01/2018  129
1   06/01/2018  131
1   07/01/2018  133
2   03/01/2018  144
2   04/01/2018  148
2   06/01/2018  150
2   07/01/2018  147

因此Stock_id = 1,则缺少日期04/01/2018。

对于Stock_id = 2,缺少日期05/01/2018,并且由于该库存的日期始于2018年3月1日,因此不应填写该日期之前的日期(因为库存是在2018年3月1日在股票市场推出的。)

因此,我希望输出以下内容:

Stock_id    Date    Stock_value
1   01/01/2018  124
1   02/01/2018  130
1   03/01/2018  136
1   04/01/2018  NA
1   05/01/2018  129
1   06/01/2018  131
1   07/01/2018  133
2   03/01/2018  144
2   04/01/2018  148
2   05/01/2018  NA
2   06/01/2018  150
2   07/01/2018  147

2 个答案:

答案 0 :(得分:1)

每组使用asfreq,但是如果大数据性能会出现问题:

df = (df.set_index( 'Date')
        .groupby('Stock_id')['Stock_value']
        .apply(lambda x: x.asfreq('D'))
        .reset_index()
        )
print (df)
    Stock_id       Date  Stock_value
0          1 2018-01-01        124.0
1          1 2018-01-02        130.0
2          1 2018-01-03        136.0
3          1 2018-01-04          NaN
4          1 2018-01-05        129.0
5          1 2018-01-06        131.0
6          1 2018-01-07        133.0
7          2 2018-01-03        144.0
8          2 2018-01-04        148.0
9          2 2018-01-05          NaN
10         2 2018-01-06        150.0
11         2 2018-01-07        147.0

编辑:

如果要以每组最小的日期时间更改值,并为最大量datetime使用某个标量,请将reindexdate_range一起使用:

df = (df.set_index( 'Date')
        .groupby('Stock_id')['Stock_value']
        .apply(lambda x: x.reindex(pd.date_range(x.index.min(), '2019-02-20')))
        .reset_index()
        )

答案 1 :(得分:0)

df.set_index(['Date', 'Stock_id']).unstack().fillna(method='ffill').stack().reset_index()