我有一个pandas数据框,其中包含两个日期列,一个定义范围的开始日期和结束日期。我希望能够收集数据框中所有行的所有日期的总计数,这些列由这些列定义。
例如,表格如下:
index start_date end date
0 '2015-01-01' '2015-01-17'
1 '2015-01-03' '2015-01-12'
结果将是每日期汇总,如:
date count
'2015-01-01' 1
'2015-01-02' 1
'2015-01-03' 2
等等。
我目前的方法有效但在大数据帧上速度非常慢,因为我在行中循环,计算范围然后循环遍历。我希望找到一个更好的方法。
目前我正在做:
date = pd.date_range (min (df.start_date), max (df.end_date))
df2 = pd.DataFrame (index =date)
df2 ['count'] = 0
for index, row in df.iterrows ():
dates = pd.date_range (row ['start_date'], row ['end_date'])
for date in dates:
df2.loc['date']['count'] += 1
答案 0 :(得分:3)
按照@Sam的建议堆叠相关列后,只需使用value_counts
。
df[['start_date', 'end date']].stack().value_counts()
修改强>
鉴于您还想计算开始日期和结束日期之间的日期:
start_dates = pd.to_datetime(df.start_date)
end_dates = pd.to_datetime(df.end_date)
>>> pd.Series(dt.date() for group in
[pd.date_range(start, end) for start, end in zip(start_dates, end_dates)]
for dt in group).value_counts()
Out[178]:
2015-01-07 2
2015-01-06 2
2015-01-12 2
2015-01-05 2
2015-01-04 2
2015-01-10 2
2015-01-03 2
2015-01-09 2
2015-01-08 2
2015-01-11 2
2015-01-16 1
2015-01-17 1
2015-01-14 1
2015-01-15 1
2015-01-02 1
2015-01-01 1
2015-01-13 1
dtype: int64
答案 1 :(得分:2)
我认为这里的解决方案是“堆叠”您的两个日期列,按日期分组,并进行计数。使用df.stack()函数。这是我汇集在一起产生一个很好的解决方案:
import datetime
df = pd.DataFrame({'Start' : [datetime.date(2016, 5, i) for i in range(1,30)],
'End':[datetime.date(2016, 5, i) for i in range(1,30)]})
df.stack().reset_index()[[0, 'level_1']].groupby(0).count()
答案 2 :(得分:1)
我会使用melt()方法:
In [76]: df
Out[76]:
start_date end_date
index
0 2015-01-01 2015-01-17
1 2015-01-03 2015-01-12
2 2015-01-03 2015-01-17
In [77]: pd.melt(df, value_vars=['start_date','end_date']).groupby('value').size()
Out[77]:
value
2015-01-01 1
2015-01-03 2
2015-01-12 1
2015-01-17 2
dtype: int64