import pandas as pd
d = [{'col1' : ' B', 'col2' : '2015-3-06 01:37:57'},
{'col1' : ' A', 'col2' : '2015-3-06 01:39:57'},
{'col1' : ' A', 'col2' : '2015-3-06 01:45:28'},
{'col1' : ' B', 'col2' : '2015-3-06 02:31:44'},
{'col1' : ' B', 'col2' : '2015-3-06 03:55:45'},
{'col1' : ' B', 'col2' : '2015-3-06 04:01:40'}]
df = pd.DataFrame(d)
df['col2'] = pd.to_datetime(df['col2'])
对于每一行,我想计算具有相同行数的行数 "col1"的值和窗口内的时间在此行的时间(包括)之前过去 10 分钟。我对快速工作的实现感兴趣
这个源在大数据集上工作得很慢:
dt = pd.Timedelta(10, unit='m')
def count1(row):
id1 = row['col1']
start_time = row['col2'] - dt
end_time = row['col2']
mask = (df['col1'] == id1) & ((df['col2'] >= start_time) & (df['col2'] <= end_time))
return df.loc[mask].shape[0]
df['count1'] = df.apply(count1, axis=1)
df.head(6)
col1 col2 count1
0 B 2015-03-06 01:37:57 1
1 A 2015-03-06 01:39:57 1
2 A 2015-03-06 01:45:28 2
3 B 2015-03-06 02:31:44 1
4 B 2015-03-06 03:55:45 1
5 B 2015-03-06 04:01:40 2
注意:"col2"列对日期敏感,而不仅仅是时间
问题是,apply
非常昂贵。 一种选择是通过cython或使用numba来优化代码。
这可能会有所帮助。
另一种选择如下:
- 创建具有 col2 时间戳的列
- 创建一个带有 id 的列,该列按 10 分钟标准对时间戳进行分组
- 使用以前创建的 id 和 col1 创建一个组合列,如
df['time_ids'].map(str) + df['col1']
- 使用
groupby
确定相等行数。像这样:df.groupby(df['combined_ids']).size()
尝试使用
df.col2=pd.to_datetime(df.col2)
df.groupby([pd.Grouper(key='col2',freq='H'),df.col1]).size().reset_index(name='count')