【问题标题】:Filling Pandas dataframe based on date columns and date range根据日期列和日期范围填充 Pandas 数据框
【发布时间】:2020-10-29 16:22:03
【问题描述】:

我有一个看起来像这样的 pandas 数据框,

    id     start    end
0   1   2020-02-01  2020-04-01
1   2   2020-04-01  2020-04-28

我有两个额外的参数,它们是日期值,比如 x 和 y。 x 和 y 将始终是该月的第一天。

我想将上面的数据框扩展为如下所示的 x = "2020-01-01" 和 y = "2020-06-01",

    id  month   status
0   1   2020-01 -1
1   1   2020-02 1
2   1   2020-03 2
3   1   2020-04 2
4   1   2020-05 -1
5   1   2020-06 -1
6   2   2020-01 -1
7   2   2020-02 -1
8   2   2020-03 -1
9   2   2020-04 1
10  2   2020-05 -1
11  2   2020-06 -1

数据框扩展为每个 id 都会有额外的months_between(x, y) 行。并制作了一个状态列并填写了值,

  • 如果月份列值等于开始列的月份,则将状态填写为 1
  • 如果月份列值大于开始列的月份但小于或等于结束列的月份,则填写为 2。
  • 如果月份列值小于开始月份的月份,则将其填充为 -1。此外,如果月份列值大于 -1 的结束填充状态月份。

我正在尝试在不循环的情况下在 pandas 中解决这个问题。我目前的解决方案是使用循环,并且需要更长的时间来运行庞大的数据集。

这里有什么可以帮助我的 pandas 函数吗?

感谢@Code Different 的解决方案。它解决了这个问题。然而,数据框可能看起来像这样的问题有一个扩展,

    id     start       end
0   1   2020-02-01  2020-02-20
1   1   2020-04-01  2020-05-10
2   2   2020-04-10  2020-04-28

一个 id 可以有多个条目。对于上面相隔 6 个月的 x 和 y,我希望数据框中的每个 id 有 6 行。该解决方案当前为数据框中的每一行创建 6 行。在处理具有数百万个 id 的数据帧时,这还可以,但并不理想。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    确保startend 列的类型为Timestamp

    # Explode each month between x and y
    x = '2020-01-01'
    y = '2020-06-01'
    
    df['month'] = [pd.date_range(x, y, freq='MS')] * len(df)
    df = df.explode('month').drop_duplicate(['id', 'month'])
    
    # Determine the status
    df['status'] = -1
    
    cond = df['start'] == df['month']
    df.loc[cond, 'status'] = 1
    
    cond = (df['start'] < df['month']) & (df['month'] <= df['end'])
    df.loc[cond, 'status'] = 2
    

    【讨论】:

    • 此解决方案运行良好。谢谢。但是,这个问题有一个扩展,我可以为一个 id 设置多行。该解决方案也适用于此。但它会额外创建许多行。例如,假设 id 1 有 2 行,x 和 y 相隔 6 个月。然后将为该 ID 制作总共 12 个月。如果我们能在 6 行中做到这一点,那将是理想的。
    • 我担心爆炸后会占用 RAM 中的空间。如果我有 1M 行并且 x 和 y 相隔 48 个月,我将有 48M 行。
    • 假设您的所有列都是 64 位(8 字节)数据类型。 4 列 * 1m 行 * 8 字节 = 32m 字节。这还不到 32MB 的内存!
    • 这听起来很合理。
    猜你喜欢
    • 1970-01-01
    • 2020-12-06
    • 2018-11-14
    • 1970-01-01
    • 2021-02-25
    • 2019-03-31
    • 2015-09-28
    • 2022-01-12
    • 2021-05-09
    相关资源
    最近更新 更多