合并熊猫和熊猫的两个时间序列在阈值时间差内提取观测值

时间:2016-07-15 16:38:51

标签: python pandas time-series

我在熊猫中有两个时间序列,在看似随机的时间观察。下面的代码将创建一些示例时间序列:

import numpy as np
import pandas as pd

s1 = pd.Series(data=np.arange(5), index=['2014-05-06 09:15:34', '2014-05-06 09:34:00',
                                         '2014-05-06 11:20:43', '2014-05-07 12:13:00',
                                         '2014-05-07 17:29:19'])
s1.index = pd.DatetimeIndex(s1.index)

s2 = pd.Series(data=np.arange(6)*10, index=['2014-05-03 10:20:09', '2014-05-06 09:13:26',
                                            '2014-05-06 09:23:38', '2014-05-06 11:09:52',
                                            '2014-05-07 12:14:08', '2014-05-07 17:35:19'])
s2.index = pd.DatetimeIndex(s2.index)

给予s1

2014-05-06 09:15:34    0
2014-05-06 09:34:00    1
2014-05-06 11:20:43    2
2014-05-07 12:13:00    3
2014-05-07 17:29:19    4
dtype: int64

s2

2014-05-03 10:20:09     0
2014-05-06 09:13:26    10
2014-05-06 09:23:38    20
2014-05-06 11:09:52    30
2014-05-07 12:14:08    40
2014-05-07 17:35:19    50
dtype: int64

我想合并这些时间序列,并提取每个时间序列中彼此之间有观察值的行。所以,使用上面的数据:

  • s2的第一个元素与s1中的任何内容都不匹配。
  • s2的第二个元素距离s1的第一个元素约2分钟内,因此这些元素匹配。
  • 等......

理想情况下,我最终得到的DataFrame列包含s1_times1_values2_times2_value,但我不是真的关于输出的确切格式。

我已经尝试了大量不同的方法,使用pd.merge,尝试使用asof等等 - 但我最终完全混淆了自己。我确信这是一个以前已经解决过的问题,但我似乎无法在网上发现与随机间隔的时间序列有关(很多是基于每小时或每天的事情)。

在熊猫中这样做的最佳方式是什么?

2 个答案:

答案 0 :(得分:3)

您可以先将reindexmethod='nearest'一起使用,然后s2中的值为uniquemerge使用此值:

print (s2.reindex(s1.index, method='nearest'))
2014-05-06 09:15:34    10
2014-05-06 09:34:00    20
2014-05-06 11:20:43    30
2014-05-07 12:13:00    40
2014-05-07 17:29:19    50
dtype: int32

print (pd.DataFrame({'s1':s1, 's2':s2.reindex(s1.index, method='nearest'), 'index_s1': s1.index}))
                               index_s1  s1  s2
2014-05-06 09:15:34 2014-05-06 09:15:34   0  10
2014-05-06 09:34:00 2014-05-06 09:34:00   1  20
2014-05-06 11:20:43 2014-05-06 11:20:43   2  30
2014-05-07 12:13:00 2014-05-07 12:13:00   3  40
2014-05-07 17:29:19 2014-05-07 17:29:19   4  50

print (pd.merge(s2.reset_index().rename(columns={0:'s2'}),
                pd.DataFrame({'s1':s1, 's2':s2.reindex(s1.index, method='nearest'), 'index_s1': s1.index}),
                on='s2').rename(columns={'index':'index_s2'}))

             index_s2  s2            index_s1  s1
0 2014-05-06 09:13:26  10 2014-05-06 09:15:34   0
1 2014-05-06 09:23:38  20 2014-05-06 09:34:00   1
2 2014-05-06 11:09:52  30 2014-05-06 11:20:43   2
3 2014-05-07 12:14:08  40 2014-05-07 12:13:00   3
4 2014-05-07 17:35:19  50 2014-05-07 17:29:19   4                

编辑:

我在tolerance中找到了新参数reindex

print (s2.reindex(s1.index, method='nearest',tolerance='10Min'))
2014-05-06 09:15:34    10.0
2014-05-06 09:34:00     NaN
2014-05-06 11:20:43     NaN
2014-05-07 12:13:00    40.0
2014-05-07 17:29:19    50.0
dtype: float64

答案 1 :(得分:0)

稍微长一点的解决方案呢?

import datetime

d = datetime.timedelta(minutes=10)
ans = [(xi, x, yi, y) for xi, x in zip(s1.index, s1) for yi, y in zip(s2.index, s2) if xi.to_datetime() - d < yi.to_datetime() < xi.to_datetime() + d]
pd.DataFrame(ans, columns=['s1_time', 's1_value', 's2_time', 's2_value'])