【问题标题】:Add different missing dates for groups of rows为行组添加不同的缺失日期
【发布时间】:2019-02-26 21:14:58
【问题描述】:

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

  • Stock_id: 股票的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 日开始,因此不应填写此日期之前的日期(因为该股票是引入在 03/01/2018 的股票市场上)。

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

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

【问题讨论】:

  • @jezrael,嗯,从我看来,是的,这回答了我的问题(尽管它有点太密集而无法立即理解)。但是,如果您还考虑到我在上面的帖子中描述的这种限制,您的解决方案是否有效:“限制是一些股票在 2018 年的某个时间被引入股市,所以显然我不想为这些填写日期库存,而这些库存不存在。”?我无法从阅读您的解决方案中真正看出;我可能只是简单地测试一下。
  • @jezrael,是的,我测试过。这绝对是错误的。它返回 2018 年的所有日期。实际上,由于您没有创建任何日期时间序列,因此它只返回它在数据集中看到的日期。因此,例如,如果数据集中完全缺少 21/05/2018 日期,那么它不会返回它,而应该返回它(至少对于该日期之后存在的股票)。
  • (这就是为什么我想我们不应该急于在此处将帖子标记为重复,但无论如何......)
  • @jezrael,首先我不是在处理股票,所以我也会给你一些虚构的数据。其次,数据没有什么令人惊讶的;您可以根据上面给出的描述自己创建一个小样本。当然,我可以创建这个样本来节省你一些时间,因为我提出这个问题,但我只是为了澄清原则上你可以自己创建一个小数据样本。
  • @jezrael,这是你的例子。这有帮助吗?

标签: python pandas dataframe


【解决方案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()
        )

【讨论】:

  • 日期现在很好,但正如我所说,“Stock_value”列到处都是 NA,我认为有些股票完全丢失了。
  • hmmm,看来是数据相关的问题。
  • 可能是,但原始数据集已正确加载并且一切都显示正常,所以我不是这将是什么样的数据问题。顺便说一句,缺少的股票是两个,据我所见,这些在原始数据集上的观察数量很少,所以我不知道这可能如何以及为什么会起作用(可能与 x.asfreq() 相关) .
  • Stock_id float64,日期对象,Stock_value float64。
  • 是的,它成功了。现在值显示正确。唯一的问题是,如果由于某种原因,股票的日期结束于例如03/12/2018 那么解决方案不会将它们扩展到例如2018 年 12 月 31 日。简而言之,限制是不生成库存不存在的日期,但它应该生成迄今为止的日期(因为库存仍然存在)或特定日期,例如2018 年 12 月 31 日。但我想我要求太多了?无论如何,感谢您迄今为止的帮助;我猜你对我和一般人都很有耐心。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    相关资源
    最近更新 更多