如何检测布尔值数组中的5“True”值?

时间:2013-01-06 17:00:10

标签: python arrays boolean

也就是说,我正在寻找一个函数true_row,以便:

true_row([False, True, True, True, True, False, False])

返回False

true_row([True, True, True, True, True, False, False])

返回True

编辑:如果它有帮助,我已经附上了目前为止的完整代码:

position_open = False

def initialize(context):
    context.stock = sid(26578)
    context.open_hours = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
    context.is_bullish = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
    context.first_check_minute = 1
    context.second_check_minute = 57

def handle_data(context, data):

    event_hour = data[context.stock].datetime.hour
    event_minute = data[context.stock].datetime.minute
    hour_open_price = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    hour_close_price = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

    global position_open

    # Hour 1 market direction checks

    if event_hour == context.open_hours[0] and event_minute == context.first_check_minute:
        hour_open_price[0] = data[context.stock].close_price

    if event_hour == context.open_hours[0] and event_minute == context.second_check_minute:
        hour_close_price[0] = data[context.stock].close_price

    if hour_open_price[0] < hour_close_price[0]:
        context.is_bullish[0] = True

    if hour_open_price[0] > hour_close_price[0]:
        context.is_bullish[0] = False

    # Hour 2 market direction checks

    if event_hour == context.open_hours[1] and event_minute == context.first_check_minute:
        hour_open_price[1] = data[context.stock].close_price

    if event_hour == context.open_hours[1] and event_minute == context.second_check_minute:
        hour_close_price[1] = data[context.stock].close_price

    if hour_open_price[1] < hour_close_price[1]:
        context.is_bullish[1] = True

    if hour_open_price[1] > hour_close_price[1]:
        context.is_bullish[1] = False

    # Same block repeated with different numbers x24 (edited out to reduce size)


    # Make Trades? - I want to edit this to detect if context.is_bullish has 5 trues in a row without needing to manually make more if statements like the one already below

    if event_hour in context.open_hours and context.is_bullish[0] == True and context.is_bullish[1] == True and context.is_bullish[2] == True and context.is_bullish[3] == True and context.is_bullish[4] == True and position_open == False:
        order(context.stock,+1000)
        log.info('Buy Order Placed')
        position_open = True

    if event_hour in context.open_hours and context.is_bullish[0] == False and position_open == True:
        order(context.stock,-1000)
        log.info('Buy Position Closed')
        position_open = False

4 个答案:

答案 0 :(得分:2)

使用itertools.groupby,它将一组相同的元素分组:

import itertools
any(len(list(g)) >= 5 and k == True for k, g in itertools.groupby(lst))

答案 1 :(得分:1)

如果您有一个列表l,则可以使用

('True' * 5) in ''.join(map(str, l))

换句话说,你的功能将是

def true_row(row):
    return ('True' * 5) in ''.join(map(str, row))

>>> def true_row(row):
...     return ('True' * 5) in ''.join(map(str, row))
... 
>>> true_row([False, True, True, True, True, False, False])
False
>>> true_row([True, True, True, True, True, False, False])
True

答案 2 :(得分:0)

如果我正确地读了你的问题,你只对布尔值而不是连续的True值感兴趣。此外,您正在处理List而不是任何可迭代的。 如果是这种情况,您可以简单地使用计数。我建议你将序列转换为List以确保你的结果在任何可迭代的

中是一致的
def true_row(row):
    return list(row).count(True) >= 5

<击>

正如OP解释的那样,他需要连续5次布尔肯定,在这种情况下,我会建议一个简单的vanilla循环和计数技术,它有一个短路机制,当它遇到5个连续的True时就退出搜索。在我测试的1000个数据的随机样本上,它快了10倍。我怀疑你可能需要在相当长的时间内迭代数千个库存数据,所以这将非常有用。

def true_row(row, length = 5):
    count = - length
    for e in row:
        if e:
            count += 1
        else:
            count = -length
        if not count:
            return True
    return False

现在速度测试

>>> seq = (choice([True, False]) for _ in xrange(1000))
>>> def David(seq):
    return any(len(list(g)) >= 5 and k == True for k, g in itertools.groupby(lst))

>>> def ARS(seq):
    return ('True' * 5) in ''.join(map(str, row))

>>> t_ab = timeit.Timer(stmt = "true_row(seq)", setup = "from __main__ import true_row, seq")
>>> t_david = timeit.Timer(stmt = "David(seq)", setup = "from __main__ import David, seq, itertools")
>>> t_ars = timeit.Timer(stmt = "ARS(seq)", setup = "from __main__ import ARS, seq")
>>> t_ab.timeit(number=1000000)
0.3180467774861455
>>> t_david.timeit(number=1000000)
10.293826538349393
>>> t_ars.timeit(number=1000000)
4.2967059784193395

即使对于必须在整个序列上迭代的较小序列,这也是更快的

>>> seq = (choice([True, False]) for _ in xrange(10))
>>> true_row(seq)
False
>>> t_ab = timeit.Timer(stmt = "true_row(seq)", setup = "from __main__ import true_row, seq")
>>> t_david = timeit.Timer(stmt = "David(seq)", setup = "from __main__ import David, seq, itertools")
>>> t_ars = timeit.Timer(stmt = "ARS(seq)", setup = "from __main__ import ARS, seq")
>>> t_ab.timeit(number=1000000)
0.32354575678039055
>>> t_david.timeit(number=1000000)
10.270037445319304
>>> t_ars.timeit(number=1000000)
3.7353719451734833

答案 3 :(得分:0)

这是一个为简单而设计的答案

def five_true(L):
    for i in range(len(L) - 5):
        if L[i:i + 5] == [True] * 5:
            return True
    return False