【问题标题】:Create a new dataframe counting of all the dates between two dates in another dataframe创建一个新的数据框,计算另一个数据框中两个日期之间的所有日期
【发布时间】:2021-10-18 12:38:53
【问题描述】:
我有一个包含大约 2,000 条记录的“start_date”和“end_date”列的数据框。我想创建一个新的数据框来计算开始日期和结束日期之间的所有日期,并创建一个数据框来汇总每个日期的这些计数,如下所示:
开始和结束数据帧
| ID |
start_date |
end_date |
| 1 |
01/01/2021 |
03/01/2021 |
| 2 |
02/01/2021 |
04/01/2021 |
| 3 |
01/01/2021 |
04/01/2021 |
日期计数数据帧
| date |
count |
| 01/01/2021 |
2 |
| 02/01/2021 |
3 |
| 03/01/2021 |
3 |
| 04/01/2021 |
2 |
【问题讨论】:
标签:
python
pandas
dataframe
【解决方案1】:
如果better performance 的中/大型DataFrame 最好避免explode 和date_range,最好使用repeat 并添加timedeltas:
df["start_date"] = pd.to_datetime(df["start_date"], dayfirst=True)
df["end_date"] = pd.to_datetime(df["end_date"], dayfirst=True)
#subtract values and convert to days
s = df["end_date"].sub(df["start_date"]).dt.days + 1
#repeat index
df = df.loc[df.index.repeat(s)].copy()
#add days by timedeltas
add = pd.to_timedelta(df.groupby(level=0).cumcount(), unit='d')
df1 = (df["start_date"].add(add)
.value_counts()
.sort_index()
.rename_axis('date')
.reset_index(name='count'))
print (df1)
date count
0 2021-01-01 2
1 2021-01-02 3
2 2021-01-03 3
3 2021-01-04 2
【解决方案2】:
您可以使用pd.date_range 为每一行获取start_date 和end_date 之间的各个日期,然后分解它,最后调用value_counts
>>> out = df.apply(lambda x: pd.date_range(x['start_date'], x['end_date']),
axis=1).explode().value_counts()
如果需要,请调用 to_frame() 传递列名以进行计数并重置和重命名索引列:
>>> out.to_frame('count').reset_index().rename(columns={'index':'date'})
输出:
date count
0 2021-01-03 3
1 2021-01-02 3
2 2021-01-04 2
3 2021-01-01 2
如果不是start_date 和end_date 列,请不要忘记将它们转换为datetime 类型:
>>> df['start_date'] = pd.to_datetime(df['start_date'], dayfirst=True)
>>> df['end_date'] = pd.to_datetime(df['end_date'], dayfirst=True)
【解决方案3】:
你可以使用:
# Convert dates in dd/mm/yyyy to datetime format
df['start_date'] = pd.to_datetime(df['start_date'], dayfirst=True)
df['end_date'] = pd.to_datetime(df['end_date'], dayfirst=True)
# Create date ranges for each row
date_rng = df.apply(lambda x: pd.date_range(x['start_date'], x['end_date']), axis=1)
# expand dates in range dates into separate rows and count unique dates
df_out = df.assign(date=date_rng).explode('date').groupby('date')['date'].count().reset_index(name='count')
结果:
print(df_out)
date count
0 2021-01-01 2
1 2021-01-02 3
2 2021-01-03 3
3 2021-01-04 2