我每个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及其各自的开始日期都要这样做。非常感谢您的帮助-谢谢!
首先,我们将您的两个日期列融为一体。然后,我们按天进行重新采样:
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]
编辑:
我不得不在一个项目中重新讨论这个问题,看起来像是在使用DataFrame。使用
pd应用
几乎快3倍:。日期范围
和数据帧。explode
df["date"] = df.apply(
lambda x: pd.date_range(x["start_date"], x["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]
使用listcomp和pd。日期范围
在列开始日期
和结束日期
的值上创建每个记录的日期列表。接下来,从listcomp的结果构造一个新的数据框,并连接回df的其他3列。最后,
设置索引
,堆栈
和重置索引
返回
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
5 123 18 CA 2019-02-22
6 123 18 CA 2019-02-23
7 123 18 CA 2019-02-24
8 123 18 CA 2019-02-25
9 123 18 CA 2019-02-26
10 123 18 CA 2019-02-27
11 123 18 CA 2019-02-28
12 123 18 CA 2019-03-01
13 123 18 CA 2019-03-02
14 123 18 CA 2019-03-03
15 123 18 CA 2019-03-04
16 123 18 CA 2019-03-05
17 123 18 CA 2019-03-06
18 123 18 CA 2019-03-07
19 123 18 CA 2019-03-08
20 123 18 CA 2019-03-09
21 123 18 CA 2019-03-10
22 123 18 CA 2019-03-11
23 123 18 CA 2019-03-12
24 123 18 CA 2019-03-13
25 123 18 CA 2019-03-14
26 123 18 CA 2019-03-15
27 123 18 CA 2019-03-16
28 123 18 CA 2019-03-17
29 123 18 CA 2019-03-18
.. ... ... ... ...
94 223 24 AZ 2019-02-03
95 223 24 AZ 2019-02-04
96 223 24 AZ 2019-02-05
97 223 24 AZ 2019-02-06
98 223 24 AZ 2019-02-07
99 223 24 AZ 2019-02-08
100 223 24 AZ 2019-02-09
101 223 24 AZ 2019-02-10
102 223 24 AZ 2019-02-11
103 223 24 AZ 2019-02-12
104 223 24 AZ 2019-02-13
105 223 24 AZ 2019-02-14
106 223 24 AZ 2019-02-15
107 223 24 AZ 2019-02-16
108 223 24 AZ 2019-02-17
109 223 24 AZ 2019-02-18
110 223 24 AZ 2019-02-19
111 223 24 AZ 2019-02-20
112 223 24 AZ 2019-02-21
113 223 24 AZ 2019-02-22
114 223 24 AZ 2019-02-23
115 223 24 AZ 2019-02-24
116 223 24 AZ 2019-02-25
117 223 24 AZ 2019-02-26
118 223 24 AZ 2019-02-27
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]