使用pandas

时间:2017-05-17 21:44:12

标签: python date pandas

我必须确定日期集之间是否存在差距(由开始日期和结束日期确定)。我有两个示例数据帧:

import pandas as pd

a = pd.DataFrame({'start_date' : ['01-01-2014', '01-01-2015', '05-01-2016'],
             'end_date' : ['01-01-2015', '01-01-2016', '05-01-2017']})

order = ['start_date', 'end_date']

a = a[order]

a.start_date = pd.to_datetime(a.start_date, dayfirst= True)
a.end_date = pd.to_datetime(a.end_date, dayfirst= True)


b = pd.DataFrame({'start_date' : ['01-01-2014', '01-01-2015', '05-01-2016', 
'05-01-2017', '01-01-2015'],
             'end_date' : ['01-01-2015', '01-01-2016', '05-01-2017',
                          '05-01-2018', '05-01-2018']})

order = ['start_date', 'end_date']

b = b[order]

b.start_date = pd.to_datetime(b.start_date, dayfirst= True)
b.end_date = pd.to_datetime(b.end_date, dayfirst= True)

a
b

对于数据框a,解决方案非常简单。按start_date排序,将end_date向下移1并减去日期,如果差异为正数,则日期会有差距。

然而,对于数据帧b实现此目标并不那么明显,因为有一个范围会扩大范围。我不确定这样做的通用方法,不会错误地找到差距。这将在分组数据(约40000组)上完成。

2 个答案:

答案 0 :(得分:1)

IIUC你可以这样做:

In [198]: (b.sort_values('start_date')
     ...:   .stack()
     ...:   .shift().diff().dt.days
     ...:   .reset_index(name='days')
     ...:   .dropna()
     ...:   .query("level_1 == 'end_date' and days != 0"))
     ...:
Out[198]:
   level_0   level_1   days
5        4  end_date -365.0
7        2  end_date -731.0

以下代码应向我们展示发现差距的指数:

In [199]: (b.sort_values('start_date')
     ...:   .stack()
     ...:   .shift().diff().dt.days
     ...:   .reset_index(name='days')
     ...:   .dropna()
     ...:   .query("level_1 == 'end_date' and days != 0")
     ...:   .loc[:, 'level_0'])
     ...:
Out[199]:
5    4
7    2
Name: level_0, dtype: int64

答案 1 :(得分:1)

这就是想法......

  • 为开始日期指定+1,为结束日期指定-1
  • 将我在所有日期订购的累计金额作为一个平面数组。
  • 累积金额为零时......我们达到了差距。
  • 日期值是第一优先级,后面是start_date。这样,当一行的end_date等于下一行的开始日期时,我们不会在添加正数之前添加负数。
  • 我使用numpy对东西进行排序并扭转并转动
  • return布局间隙开始的布尔掩码。
def find_gaps(b):
    d1 = b.values.ravel()
    d2 = np.tile([1, -1], len(d1) // 2)
    s = np.lexsort([-d2, d1])
    u = np.empty_like(s)
    r = np.arange(d1.size)
    u[s] = r
    return d2[s].cumsum()[u][1::2] == 0

演示

find_gaps(b)

array([False, False, False, False,  True], dtype=bool)
find_gaps(a)

array([False,  True,  True], dtype=bool)