【问题标题】:Expand df with range of dates to one row per day将具有日期范围的 df 扩展到每天一行
【发布时间】:2020-02-10 10:14:47
【问题描述】:

我有一个 df,其中每个项目包含一个日期范围的行,我需要将其扩展为每个项目每天包含一行。

看起来像这样:

  from       to         id
1 25/02/2019 27/02/2019 A
2 15/07/2019 16/07/2019 B

我想要这个:

  date       id
1 25/02/2019 A
2 26/07/2019 A
3 27/07/2019 A
4 15/07/2019 B
5 16/07/2019 B

我设法编写了一个有效的代码,但它需要一个多小时才能运行,所以我想知道是否有更有效的方法来做到这一点。

我的代码:

df_dates = pd.DataFrame()

for i in range(len(df)):

    start = df.loc[i]['from']
    end = df.loc[i]['to'] + np.timedelta64(1,'D') #includes last day of the range
    dates = np.arange(start, end, dtype='datetime64[D]')

    temp = pd.DataFrame()
    temp = temp.append([df.loc[i]]*len(dates), ignore_index=True)
    temp['datadate'] = dates

    df_dates = df_dates.append(temp, ignore_index=True)

这需要很长时间,因为实际范围大约是 50 年,有超过 1700 个项目,所以新的 df 很大,但也许你知道一个更快地做同样事情的技巧:)

【问题讨论】:

    标签: python pandas for-loop date-range


    【解决方案1】:

    您可以先转换日期为to_datetime 的列。然后使用itertuplesdate_rangeconcat 来创建新的扩展DataFrame

    df['from1'] = pd.to_datetime(df['from'])
    df['to1'] = pd.to_datetime(df['to'])
    
    L = [pd.Series(r.id, pd.date_range(r.from1, r.to1)) for r in df.itertuples()]
    df1 = pd.concat(L).reset_index()
    df1.columns = ['date','id']
    print (df1)
            date id
    0 2019-02-25  A
    1 2019-02-26  A
    2 2019-02-27  A
    3 2019-07-15  B
    4 2019-07-16  B
    

    【讨论】:

    • 如果我们有多个其他属性作为id怎么办? @jezrael
    【解决方案2】:

    试试:

    df['from'] = pd.to_datetime(df['from'])
    df['to'] = pd.to_datetime(df['to'])
    pd.concat([pd.DataFrame({'date': pd.date_range(row['from'], row['to'], freq='D'), 'id': row['id']})
               for i, row in df.iterrows()], ignore_index=True)
            date id
    0 2019-02-25  A
    1 2019-02-26  A
    2 2019-02-27  A
    3 2019-07-15  B
    4 2019-07-16  B
    

    【讨论】:

    • 循环中i的作用是什么?我知道没有它就行不通,但我无法弄清楚它实际上做了什么,因为它在代码中没有其他地方
    • iterrows() 返回行的索引和值,i 是本例中的索引。您可以将其替换为_
    • 如果我们有多个其他属性,比如 id 怎么办?那么我们如何扩展它呢? @luigigi
    猜你喜欢
    • 1970-01-01
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    相关资源
    最近更新 更多