如何在时间索引的DataFrame中查找时间重叠

时间:2015-05-06 23:45:12

标签: python pandas time-series

我有一个DataFrame,其中索引是date_time,列中的数据是随时间交错的。也许最好的解释是展示这个DF:

>>> c
                     A           B          C          D
2015-01-01  0.09607408         NaN        NaN        NaN
2015-01-02         NaN  0.03582221        NaN        NaN
2015-01-03   0.2750026         NaN        NaN        NaN
2015-01-04         NaN    0.892619        NaN        NaN
2015-01-05   0.8574456         NaN        NaN        NaN
2015-01-06         NaN  0.08720886        NaN        NaN
2015-01-07   0.7091732         NaN        NaN        NaN
2015-01-08         NaN  0.09354087        NaN        NaN
2015-01-09     0.60924         NaN        NaN        NaN
2015-01-10         NaN   0.1966458        NaN        NaN
2015-01-11         NaN         NaN  0.5135616        NaN
2015-01-12         NaN         NaN        NaN  0.3015004
2015-01-13         NaN         NaN  0.5717249        NaN
2015-01-14         NaN         NaN        NaN  0.5416951
2015-01-15         NaN         NaN  0.1031428        NaN
2015-01-16         NaN         NaN        NaN  0.2944353
2015-01-17         NaN         NaN   0.642031        NaN
2015-01-18         NaN         NaN        NaN  0.2546383
2015-01-19         NaN         NaN  0.6536632        NaN
2015-01-20         NaN         NaN        NaN  0.9877289
2015-01-21         NaN         NaN        NaN        NaN

现在,由于A列和B列在一段时间内交错并且存在大量重叠,因此我会将其视为可比分析用于分析目的。

同样地,C和D数据都在彼此实质上重叠的时间段内发生,但是与A / B时间段没有重叠。

我试图用一种灵巧的方式将A / B和C / D识别为一起组合。我可以设想用c.A.first_valid_index()等来做这件事。如果我这样做,这都是非常代数的。我想知道是否有一种灵巧的方式来使用一些内置的"重叠"功能来自时间序列工具。我找不到任何这样的东西 - 希望它存在。 TIA

制作上述设计示例DF的代码是:

t = pd.date_range('20150101',periods=21)
ti = t.to_datetime()

c = pd.DataFrame(index = ti, columns=['A','B','C','D'])

c.A[0:10:2] = np.random.rand(5)
c.B[1:11:2] = np.random.rand(5)
c.C[10:20:2] = np.random.rand(5)
c.D[11:21:2] = np.random.rand(5)

2 个答案:

答案 0 :(得分:1)

这是在路上。

将两列组合传递给overlap函数。这样做是什么

def overlap(cols):
    v = c[cols[0]].fillna(c[cols[1]]).notnull()
    days = (v[v].index.max() - v[v].index.min()).days + 1
    length = len(v[v])
    return 'Overlap' if length == days else 'No'

它将使用NaNcols[0]填充cols[1]的{​​{1}}值,然后仅使用c[cols[0]].fillna(c[cols[1]])

提取非空值

之后,找到notnul()max日期以获取日期范围,即min。然后,找出重叠序列的长度是否与days

匹配

现在,使用days

迭代列组合
overlap(cols)

答案 1 :(得分:1)

不确定使用.first_valid_index()有什么问题 - 对我来说看起来很光滑:

periods = pd.Series([pd.date_range(c[col].first_valid_index(), 
                                   c[col].last_valid_index(), freq='D') 
                     for col in c.columns.tolist()], index=c.columns)
overlaps = periods.apply(lambda x: periods.apply(lambda y: x.isin(y).any()))
print overlaps

提供易于使用的重叠矩阵:

       A      B      C      D
A   True   True  False  False
B   True   True  False  False
C  False  False   True   True
D  False  False   True   True

检查重叠是否微不足道:

print overlaps.loc['A','B']
# True
print overlaps.loc['A','C']
# False

或将其转换为系列:

overlaps = overlaps.stack()
print overlaps

A  A     True
   B     True
   C    False
   D    False
B  A     True
   B     True
   C    False
   D    False
C  A    False
   B    False
   C     True
   D     True
D  A    False
   B    False
   C     True
   D     True
dtype: bool

并在没有.loc的情况下访问它:

print overlaps['A','B']
# True
print overlaps['A','C']
# False