Python-具有数百万行的两个数据帧中日期的矢量化差

时间:2018-06-23 14:56:51

标签: python pandas datetime vectorization counting

我有两个数据框:

Date                  Variable
2013-04-01 05:00:00     S   
2013-04-01 05:00:00     A   
2013-04-01 05:10:00     S   
2013-04-01 05:20:00     A
2013-04-01 05:25:00     S   
2013-04-01 05:35:00     S

并且:

Date                  Variable
2013-04-01 04:50:00     A   
2013-04-01 05:00:00     A   
2013-04-01 05:05:00     S   
2013-04-01 05:15:00     S
2013-04-01 05:35:00     S   
2013-04-01 05:40:00     S

我的目标是计算第二个数据帧上每个日期之前和之后20分钟的第一个数据帧上的日期数。因此,我需要做的是遍历第二个数据帧上的所有日期,并计算每个特定日期之后20分钟和20分钟后第一个数据帧中有多少个日期。另外,我想考虑变量A或S的出现次数,换句话说,Nr_var_20_bef列具有相同变量的日期数20min bef。因此,输出将类似于:

Date               Variable   Nr_20_bef   Nr_20_aft  Nr_var_20_bef  Nr_var_20_after  
2013-04-01 04:50:00     A        0            3             0             1
2013-04-01 05:00:00     A        2            4             1             2
2013-04-01 05:05:00     S        2            3             1             2
2013-04-01 05:15:00     S        3            3             2             2
2013-04-01 05:35:00     S        3            1             2             1
2013-04-01 05:40:00     S        3            0             2             0

我的主要问题是两个数据框都有超过一百万行,这意味着我不能使用for循环或应用pandas,因为使用如此巨大的数据框占用了太多时间。预先非常感谢。

1 个答案:

答案 0 :(得分:1)

这是一个棘手的问题!我可以为您提供部分解决方案,希望这足以使您入门。

您应该研究可以利用DateTime索引的熊猫rolling方法。请注意,据我所知,滚动功能只能查看上一个时间段,而不能查看将来的时间段。此解决方案根据barfoo的一组合并时间来计算过去20分钟内出现的bar列的实例数,我相信这是您要的

import pandas as pd
import numpy as np

# Attempting to generate some similar data
np.random.seed(0)
rng = pd.date_range('4/1/2013', periods=1000, freq='5T', name='Date')
df = pd.DataFrame({'Variable': np.random.choice(['S', 'A'], 1000)}, index=rng)
df1 = df.sample(frac=0.5)
df2 = df.sample(frac=0.5)

merged = df1.merge(df2, how='outer', left_index=True, right_index=True, suffixes=['_foo', '_bar'])

# pandas can't found objects, but can count bools
m = merged.notnull()

# Rolling functions can't count "after", only "before" or "center"
merged['Nr_20_bef'] = m.Variable_bar.rolling('20T').sum()

print(merged.head(10))

                    Variable_foo Variable_bar  Nr_20_bef
# Date
# 2013-04-01 00:05:00            A          NaN        0.0
# 2013-04-01 00:10:00            A          NaN        0.0
# 2013-04-01 00:15:00          NaN            S        1.0
# 2013-04-01 00:20:00            A            A        2.0
# 2013-04-01 00:25:00            A          NaN        2.0
# 2013-04-01 00:40:00          NaN            A        1.0
# 2013-04-01 00:45:00            A            A        2.0
# 2013-04-01 00:50:00          NaN            A        3.0
# 2013-04-01 01:05:00          NaN            A        2.0
# 2013-04-01 01:10:00            S            S        2.0

生成Nr_20_bef列的速度非常快,用我两岁的笔记本电脑上的1000万行,大约需要1秒。例如,如果您只想计算“ S”个字符,则可以执行m = merged == 'S'