英文:
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 > 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
If you want to optimize this, you could exit early as soon as you see an upward peak.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论