如何将两个日期列表合并成一系列日期间隔? [英] How to merge two lists of dates into a series of date intervals?

查看:274
本文介绍了如何将两个日期列表合并成一系列日期间隔?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有开始日期列表和结束日期列表。他们被排序...

  start_dates = [
datetime.date(2009,11,5),datetime .date(2009,11,13),
datetime.date(2009,11,25),datetime.date(2009,11,26),
datetime.date(2009,12,4) ,datetime.date(2009,12,7),
datetime.date(2009,12,29),datetime.date(2009,12,30)]

end_dates = [
datetime.date(2009,10,1),datetime.date(2009,10,2),
datetime.date(2009,10,9),datetime.date(2009,10,12) ,
datetime.date(2009,11,4),datetime.date(2009,12,14),
datetime.date(2009,12,15)]

我们需要一系列时间段,使用start_date开始一个句点,end_date要结束句点。时间段不能重叠:每个周期必须在下一个开始之前结束,也不得在最后一个结束的那一天开始。如果最后有一个start_date没有合适的end_date匹配,请使用作为最终结束日期。



因此,以上输入生成:

  result =(
(datetime.date(2009,11,5 ),datetime.date(2009,12,14)),
(datetime.date(2009,12,29),无)

pre>

我在for循环中使用for循环,想知道是否有更好的方法。性能令人感兴趣,因为它将在40年的时间内应用于数千种场景;一些列表涉及数千个日期。



X ----



说实话令人惊讶的是,在解决这个问题上遇到了很多麻烦,我会再次尝试通过揭示应用程序,也许这个抽象可以很难看出...



开始日期代表我们收到建议购买股票的日期。结束日期是我们收到销售建议的日期。建议的来源是不同的,我们正在回顾如果我们从一个来源使用买卖建议,但是另一个来源的建议,会发生什么。因此,我们有两个序列的日期,我们想要解决成对或间隔,我们将在股票中持有一个位置。



因此,我们采取日期从start_dates买股票。所以在11月5日我们买了一个职位。现在我们通过end_dates寻找,当我们第一次被告知要出售它 - 12月14日。现在重复等待购买建议,然后卖出建议。所以你交替列表来获得一个逻辑的日期对序列。如果最后我们持有一个空头头寸,我们会注意到,通过使用或提供一个特殊的日期来关闭。

解决方案

我终于确定了:

  trades = ] 
enddate = datetime.date(1900,1,1)
try:
在startdates中的startdate:
如果enddate< = startdate:
enddate = enddates .next()
while enddate< = startdate:
enddate = enddates.next()
trades.append((startdate,enddate))
除了StopIteration:
trades.append((startdate,None))

感谢那些提问和回答的人。因为没有理性的理由,这个小小的难题成了我的固定,但我觉得终于我已经做到了死亡,应该继续我的生活。最终真的很简单 - 令人惊讶的是,这是很简单的!


I have list of start dates, and a list of end dates. They're sorted...

start_dates = [
    datetime.date(2009, 11, 5), datetime.date(2009, 11, 13), 
    datetime.date(2009, 11, 25), datetime.date(2009, 11, 26), 
    datetime.date(2009, 12, 4), datetime.date(2009, 12, 7), 
    datetime.date(2009, 12, 29), datetime.date(2009, 12, 30)]

end_dates = [
    datetime.date(2009, 10, 1), datetime.date(2009, 10, 2), 
    datetime.date(2009, 10, 9), datetime.date(2009, 10, 12), 
    datetime.date(2009, 11, 4), datetime.date(2009, 12, 14), 
    datetime.date(2009, 12, 15)]

We want a sequence of time periods which use a start_date to start a period and an end_date to end the period. The time periods can't overlap: each period must end before the next one starts, nor start on the day the last one ended. If, at the end, there is a start_date with no suitable end_date to match, use None as the final end date.

Thus the input above generates:

result = (
  (datetime.date(2009, 11, 5), datetime.date(2009, 12, 14)),
  (datetime.date(2009, 12, 29), None)
)

I'm using for-loops inside for-loops and wonder if there is not a better way. Performance is of interest since it will be applied to thousands of scenarios over a 40 year span; some of the lists involve thousands of dates.

X----

To be honest I'm surprised people are having so much trouble understanding the problem... I'll try again by revealing the application, perhaps the abstraction is making it hard to visualize...

The start dates represent dates on which we receive advice to buy a share. The end dates are dates on which which we received advice to sell it. The sources of advice are different and we are backtesting what would happen if we used the buy advice from one source, but the sell advice from another. Thus we have two sequences of dates which we want to resolve into pairs - or intervals - over which we would have held a position in the stock.

Thus we take a date from the start_dates buy the stock. So on Nov 5 we buy a position. Now we work through the end_dates looking for when we would've first been told to sell it - Dec 14. Now repeat by waiting the buy advice, then the sell advice. So you alternate the lists to get a logical sequence of date pairs. If at the end we're holding an open position we note that by using None or supplying a special date to close with.

解决方案

I've finally nailed it down to:

    trades = []
    enddate = datetime.date(1900, 1, 1)
    try:
        for startdate in startdates:
            if enddate <= startdate:
                enddate = enddates.next()
                while enddate <= startdate:
                    enddate = enddates.next()
                trades.append((startdate, enddate))
    except StopIteration:
        trades.append((startdate, None))

Thanks to those who asked questions and answered. For no rational reason this little puzzle became a fixation for me but I think finally I have done this to death and should move on with my life. It's really very simple in the end - astonishing how much work it took to make it this plain!

这篇关于如何将两个日期列表合并成一系列日期间隔?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆