编辑:标题已更改,以反映map
的效率不如for
循环。
原标题:在比较日期时用地图替换for循环
我有一个连续日期列表date_list
和一个数据帧df
,其中包含,就现在而言,包含一个名为Event Date
的列,其中包含事件发生的日期:
Index Event Date
0 02-01-20
1 03-01-20
2 03-01-20
我想知道在给定日期之前发生了多少事件,格式为:
Date Events
01-01-20 0
02-01-20 1
03-01-20 3
我目前这样做的方法如下:
for date in date_list:
event_rows = df.apply(lambda x: True if x['Event Date'] > date else False , axis=1)
event_count = len(event_rows[event_rows == True].index)
temp = [date,event_count]
pre_df_list.append(temp)
其中列表pre_df_list
稍后被转换为数据帧。
这种方法很慢,看起来很不雅,但我正在努力寻找一种有效的方法。
我认为它应该是类似于的东西
map(lambda x,y: True if x > y else False, df['Event Date'],date_list)
但这会成对比较列表中的每个项目,这不是我想要的。
我很感激当我有工作代码时寻求帮助可能很奇怪,但我正在努力减少对循环的依赖,因为它们目前对我来说有点像拐杖。此外,我在完整的数据中有多个不同的事件需要跟踪,每个事件循环大约1000个日期的速度将非常慢。
使用groupby()
和size()
获取每个日期的计数,使用cumsum()
获取累积和,即包括特定行之前的所有日期。
from datetime import date, timedelta
import random
import pandas as pd
# example data
dates = [date(2020, 1, 1) + timedelta(days=random.randrange(1, 100, 1)) for _ in range(1000)]
df = pd.DataFrame({'Event Date': dates})
# count events <= t
event_counts = df.groupby('Event Date').size().cumsum().reset_index()
event_counts.columns = ['Date', 'Events']
event_counts
Date Events
0 2020-01-02 13
1 2020-01-03 23
2 2020-01-04 34
3 2020-01-05 42
4 2020-01-06 51
.. ... ...
94 2020-04-05 972
95 2020-04-06 981
96 2020-04-07 989
97 2020-04-08 995
98 2020-04-09 1000
然后,如果date_list
文件中的日期不存在于数据帧中,请将date_list
转换为数据帧并合并以前的结果。fillna(method='ffill')
将填充数据中间的间隙,而最后一个fillna(0)
则表示列的开头有间隙。
date_list = [date(2020, 1, 1) + timedelta(days=x) for x in range(150)]
date_df = pd.DataFrame({'Date': date_list})
merged_df = pd.merge(date_df, event_counts, how='left', on='Date')
merged_df.columns = ['Date', 'Events']
merged_df = merged_df.fillna(method='ffill').fillna(0)
除非我误解了你的目标,否则在我看来,你可以简单地使用pandas DataFrames的能力来与单个值进行比较,并像这样对数据帧进行切片:
>>> df = pd.DataFrame({'event_date': [date(2020,9, 1), date(2020, 9, 2), date(2020, 9, 3)]})
>>> df
event_date
0 2020-09-01
1 2020-09-02
2 2020-09-03
>>> df[df.event_date > date(2020, 9, 1)]
event_date
1 2020-09-02
2 2020-09-03