pandas 将带有开始和结束日期的 Dataframe 转换为每日数据

5rgfhyps  于 2023-02-28  发布在  其他
关注(0)|答案(2)|浏览(128)

每个ID都有一条记录,包含开始日期和结束日期

id  age state   start_date  end_date
123 18  CA     2/17/2019    5/4/2019
223 24  AZ     1/17/2019    3/4/2019

我想为开始日和结束日之间的每一天创建一条记录,以便将每日活动数据连接到该记录。

id  age state   start_date
123 18  CA      2/17/2019
123 18  CA      2/18/2019
123 18  CA      2/19/2019
123 18  CA      2/20/2019
123 18  CA      2/21/2019
            …
123 18  CA      5/2/2019
123 18  CA      5/3/2019
123 18  CA      5/4/2019

当然,对数据集中的所有id和它们各自的开始日期都要这样做。

b91juud3

b91juud31#

df["date"] = df.apply(
    lambda row: pd.date_range(row["start_date"], row["end_date"]),
    axis=1
)
df = (
    df.explode("date", ignore_index=True)
    .drop(columns=["start_date", "end_date"])
)
    • 产出**
id  age state       date
0    123   18    CA 2019-02-17
1    123   18    CA 2019-02-18
2    123   18    CA 2019-02-19
3    123   18    CA 2019-02-20
4    123   18    CA 2019-02-21
..   ...  ...   ...        ...
119  223   24    AZ 2019-02-28
120  223   24    AZ 2019-03-01
121  223   24    AZ 2019-03-02
122  223   24    AZ 2019-03-03
123  223   24    AZ 2019-03-04

[124 rows x 4 columns]

原始答案:

一米三纳一x,一米四纳一x,一米五纳一x和一米六纳一x
首先,我们将两个日期列melt(反透视)为一列,然后按天resample

melt = df.melt(id_vars=['id', 'age', 'state'], value_name='date').drop('variable', axis=1)
melt['date'] = pd.to_datetime(melt['date'])

melt = melt.groupby('id').apply(lambda x: x.set_index('date').resample('d').first())\
           .ffill()\
           .reset_index(level=1)\
           .reset_index(drop=True)
    • 产出**
date     id   age state
0   2019-02-17  123.0  18.0    CA
1   2019-02-18  123.0  18.0    CA
2   2019-02-19  123.0  18.0    CA
3   2019-02-20  123.0  18.0    CA
4   2019-02-21  123.0  18.0    CA
..         ...    ...   ...   ...
119 2019-02-28  223.0  24.0    AZ
120 2019-03-01  223.0  24.0    AZ
121 2019-03-02  223.0  24.0    AZ
122 2019-03-03  223.0  24.0    AZ
123 2019-03-04  223.0  24.0    AZ

[124 rows x 4 columns]
owfi6suc

owfi6suc2#

对列start_dateend_date的值使用listcomp和pd.date_range,为每个记录创建日期列表。接下来,根据listcomp的结果构造新的 Dataframe ,并联接回df的其他3列。最后,联接回set_indexstackreset_index

a = [pd.date_range(*r, freq='D') for r in df[['start_date', 'end_date']].values]
(df[['id', 'age', 'state']]
    .join(pd.DataFrame(a)).set_index(['id', 'age', 'state'])
    .stack().droplevel(-1).reset_index()
    )

Out[187]:
      id  age state          0
0    123   18    CA 2019-02-17
1    123   18    CA 2019-02-18
2    123   18    CA 2019-02-19
3    123   18    CA 2019-02-20
4    123   18    CA 2019-02-21
..   ...  ...   ...        ...
119  223   24    AZ 2019-02-28
120  223   24    AZ 2019-03-01
121  223   24    AZ 2019-03-02
122  223   24    AZ 2019-03-03
123  223   24    AZ 2019-03-04

[124 rows x 4 columns]

相关问题