【问题标题】:Length (count) of sequences with start and end condition Python具有开始和结束条件 Python 的序列的长度(计数)
【发布时间】:2020-10-30 18:34:12
【问题描述】:

我有一些加速度数据,我试图计算给定一组条件的序列长度。在这种情况下,我想计算加速度moves > 2.78然后回落到0以下时的序列长度。

一个例子是

[-1.1, -1, 0, 1.2, 1.8, 2, 2.88, 2.86, 2.53, 1.98, 1.21, 0.89, 0.11, -0.21]

这里的返回结果是 7 (2.88, 2.86, 2.53, 1.98, 1.21, 0.89, 0.11)

我之前已经这样做了,以使用以下代码严格识别 >2.78 的序列长度。我需要在此基础上使用 0 作为端点来提供长度。

def get_Accel_lengths( array ) :
    s = ''.join( ['0' if i < 2.78 else '1' for i in resultsQ4['AccelInt']] )
    parts = s.split('0')
    return [len(p) for p in parts if len(p) > 0]
Q4Accel = get_Accel_lengths(resultsQ4['AccelInt'])
Q4Accel = pd.DataFrame(Q4Accel)
Q4Accel 

使用上面的例子,这段代码的结果是2 (2.88, 2.86)

【问题讨论】:

  • 嗨,安,感谢您的输入,这仅计算 >2.78 的值,我需要计算 >2.78 之后的后续值,一直到 0。
  • 我可能明白我需要计算>2.78之后的后续值,但我不明白一直回到0。

标签: python python-3.x conditional-statements


【解决方案1】:

如果数据集中多次发生这种情况,这会起作用吗? 我想识别每一个。

让我们从takewhiledropwhile 切换到groupby,并使用全局布尔标志来识别多个序列。我只是将您的数据连接到自身上以模拟两个序列:

from itertools import groupby

def keyfunc(datum):
    global in_sequence

    if datum < 0:
        in_sequence = False
    elif datum > 2.78:
        in_sequence = True

    return in_sequence

data = [
    -1.1, -1, 0, 1.2, 1.8, 2, 2.88, 2.86,
    2.53, 1.98, 1.21, 0.89, 0.11, -0.21,
    -1.1, -1, 0, 1.2, 1.8, 2, 2.88, 2.86,
    2.53, 1.98, 1.21, 0.89, 0.11, -0.21,
]

sequences = []
in_sequence = False

for valid, sequence in groupby(data, keyfunc):
    if valid:
        sequences.append(list(sequence))

print(*sequences, sep='\n')
print(*map(len, sequences), sep='\n')

输出

> python3 test.py
[2.88, 2.86, 2.53, 1.98, 1.21, 0.89, 0.11]
[2.88, 2.86, 2.53, 1.98, 1.21, 0.89, 0.11]
7
7
> 

是否可以收紧它,但只提供 len 数字 因为我想然后转换成 df 并导出到 csv?

大概是这样的:

from itertools import groupby

data = [
    -1.1, -1, 0, 1.2, 1.8, 2, 2.88, 2.86,
    2.53, 1.98, 1.21, 0.89, 0.11, -0.21,
    -1.1, -1, 0, 1.2, 1.8, 2, 2.88, 2.86,
    2.53, 1.98, 1.21, 0.89, 0.11, -0.21,
]

def sequence_lengths(data):
    in_sequence = False

    def keyfunc(datum):
        nonlocal in_sequence

        if datum < 0:
            in_sequence = False
        elif datum > 2.78:
            in_sequence = True

        return in_sequence

    lengths = []

    for valid, sequence in groupby(data, keyfunc):
        if valid:
                lengths.append(len(list(sequence)))

    return lengths

print(sequence_lengths(data))

【讨论】:

  • 这看起来很有希望。我会尝试使用我的数据并通知您!
  • 完美!它运作良好。是否可以收紧它,只提供我想要的 len 数字然后转换为 df 并导出到 csv?
  • @Jake,我尝试按照您的建议将其打包。您可能需要根据需要对其进行调整(例如返回值)。您还可以对其进行修改以将限制作为参数传递,而不是对其进行硬编码。
【解决方案2】:

使用itertools.dropwhiletakewhile

l = [-1.1, -1, 0, 1.2, 1.8, 2, 2.88, 2.86, 2.53, 1.98, 1.21, 0.89, 0.11, -0.21]
list(takewhile(lambda x: x > 0, dropwhile(lambda x: x < 2.78, l)))

输出:

[2.88, 2.86, 2.53, 1.98, 1.21, 0.89, 0.11]

或者只是为了得到len

sum(1 for _ in takewhile(lambda x: x > 0, dropwhile(lambda x: x < 2.78,  l)))
# 7

【讨论】:

  • 非常感谢克里斯。因此,这可以识别数字,但是如何仅计算每个序列中有多少,例如7在这里?另外,如果数据集中多次发生这种情况,这会起作用吗?我想识别每一个。谢谢!
  • @Jake 我已经更新了答案以获得len。不幸的是,如果您要提取多次,这将不起作用 :(
  • 啊,这正是我所需要的,只是出现了多次。这只抓住了第一个。感谢您让我走到这一步!
猜你喜欢
  • 1970-01-01
  • 2011-08-28
  • 2014-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-08
  • 1970-01-01
相关资源
最近更新 更多