根据日期列和日期范围填充熊猫数据框

时间:2020-10-29 16:22:03

标签: python 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,将在(x,y)之间增加额外的months_between行。然后创建一个状态列并填充值,以使

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

我正在尝试在熊猫中解决此问题而不循环。我目前拥有的解决方案是使用循环,并且需要更长的时间才能运行大型数据集。

这里有任何熊猫功能可以帮助我吗?

感谢@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可以包含多个条目。对于上面的x和y(相隔6个月),我想在数据框中为每个id创建6行。该解决方案当前为数据框中的每一行创建6行。可以,但在处理具有数百万个ID的数据框时并不理想。

1 个答案:

答案 0 :(得分: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