如何检测列表中的上升和下降趋势

huangapple go评论62阅读模式
英文:

How to detect up and down trend in a list

问题

下面是代码的翻译部分:

a1 = [8, 6, 4, 1, -2, -6, 5, 8, 9, 87] 
a2 = [8, 6, 4, 1, -2, -6, 5, -8, 9, 10]

代码部分:

def detect_upward_downward(data):
    is_upward = False
    is_downward = False

    for i in range(len(data) - 1):
        if data[i] < data[i + 1]:
            is_upward = True
        elif data[i] > data[i + 1]:
            is_downward = True

    if is_upward and is_downward:
        return 'NG'
    else:
        return 'OK'

result_a1 = detect_upward_downward(a1)
result_a2 = detect_upward_downward(a2)

print(result_a1)  # 期望输出 'OK'
print(result_a2)  # 期望输出 'NG'

希望这对你有所帮助。

英文:

A lot of python list with some data, how to detect the data in the list is meet downward then upward.
For example:

a1 = [8,6,4,1,-2,-6,5,8,9,87] 
a2 = [8,6,4,1,-2,-6,5,-8,9,10]

where data in a1 is downard then upward,expect print 'OK'
but data in a2 is downard then upward then downard last upward, expect print 'NG'
how to do it by python?

答案1

得分: 3

你可以计算连续差值的符号,然后只保留不同的部分。如果结果是 [-1, 1],那么返回 OK,否则返回 NG

import numpy as np

def check(lst):
    # 连续差值的符号
    s = np.sign(np.diff(lst))
    # 用于去重连续值的掩码
    m1 = np.r_[True, s[:-1]!=s[1:]]
    # 用于去除平行线的掩码
    m2 = s != 0
    # 如果两个掩码都为True,则返回'OK',否则返回'NG'
    return 'OK' if s[m1&m2].tolist() == [-1, 1] else 'NG'

check(a1)
# 'OK'

check(a2)
# 'NG'

check([2,1,1,2])
# 'OK'

中间步骤:

第一个例子

lst

[8, 6, 4, 1, -2, -6, 5, 8, 9, 87]

s = np.sign(np.diff(lst))

array([-1, -1, -1, -1, -1, 1, 1, 1, 1])

s[np.r_[True, s[:-1]!=s[1:]]].tolist()

[-1, 1]

第二个例子

lst

[8, 6, 4, 1, -2, -6, 5, -8, 9, 10]

s = np.sign(np.diff(lst))

array([-1, -1, -1, -1, -1, 1, -1, 1, 1])

s[np.r_[True, s[:-1]!=s[1:]]].tolist()

[-1, 1, -1, 1]


<details>
<summary>英文:</summary>

You can compute the sign of the successive differences, then only keep the different ones. If this yields `[-1, 1]` this is a `OK`, else a `NG`:

import numpy as np

def check(lst):
# sign of successive difference
s = np.sign(np.diff(lst))
# mask to deduplicate successive values
m1 = np.r_[True, s[:-1]!=s[1:]]
# mask to remove flat lines
m2 = s != 0
# OK if both masks are True else NG
return 'OK' if s[m1&m2].tolist() == [-1, 1] else 'NG'

check(a1)

'OK'

check(a2)

'NG'

check([2,1,1,2])

'OK'

Intermediates:

first example

lst

[8, 6, 4, 1, -2, -6, 5, 8, 9, 87]

s = np.sign(np.diff(lst))

array([-1, -1, -1, -1, -1, 1, 1, 1, 1])

s[np.r_[True, s[:-1]!=s[1:]]].tolist()

[-1, 1]

second example

lst

[8, 6, 4, 1, -2, -6, 5, -8, 9, 10]

s = np.sign(np.diff(lst))

array([-1, -1, -1, -1, -1, 1, -1, 1, 1])

s[np.r_[True, s[:-1]!=s[1:]]].tolist()

[-1, 1, -1, 1]


</details>



# 答案2
**得分**: 2

你可以每次迭代列表时按照三个项目一组进行计数,记录你看到的下降或上升峰的类型。最后,如果只有一个下降峰,则返回`True`,否则返回`False`。

```python
def one_downward_peak(data):
    upward_peaks = 0
    downward_peaks = 0

    for i in range(len(data) - 2):
        a, b, c = data[i:i+3]
        if a > b < c:
            downward_peaks += 1
        elif a < b > c:
            upward_peaks += 1

    return upward_peaks == 0 and downward_peaks == 1
>>> one_downward_peak([8,6,4,1,-2,-6,5,8,9,87])
True
>>> one_downward_peak([8,6,4,1,-2,-6,5,-8,9,10])
False

如果你想要优化这段代码,你可以在发现第一个上升峰时提前退出。

英文:

You can iterate through the list three items at a time and count the types of peaks that you see, either downward or upwards. At the end, return True if there is only one downward peak, False otherwise.

def one_downward_peak(data):
    upward_peaks = 0
    downward_peaks = 0

    for i in range(len(data) - 2):
        a, b, c = data[i:i+3]
        if a &gt; b &lt; c:
            downward_peaks += 1
        elif a &lt; b &gt; c:
            upward_peaks += 1

    return upward_peaks == 0 and downward_peaks == 1
&gt;&gt;&gt; one_downward_peak([8,6,4,1,-2,-6,5,8,9,87])
True
&gt;&gt;&gt; one_downward_peak([8,6,4,1,-2,-6,5,-8,9,10])
False

If you want to optimize this, you could exit early as soon as you see an upward peak.

huangapple
  • 本文由 发表于 2023年2月18日 15:40:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75491885.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定