Максимумы и минимумы точки кривой в Python
У меня есть данные от датчика смещения, значения дельты для одной итерации выглядят так. 0, 1, 2, 4, 7, 9, 14, 24, 14, 10, 9, 7, 3 2, 1, 0, 0, 0, 0, -1, -3, -5, -7, -9, -14, -24, -14, -9, -8, -6, -4, -3, -1, 0, 0, 0. (другие итерации также имеют ту же схему).
Я заинтересован в максимумах и минимумах точек кривой. Я начинаю с начальной позиции и возвращаюсь к этой позиции для циклов для линии (я взял частичную сумму значений, чтобы получить общее смещение или линию). Частичная сумма выглядит следующим образом [0, 1, 3, 7, 14, 23, 37, 61, 75, 85, 94, 101, 104, 106, 107, 107, 107, 107, 107, 106, 103, 98, 91, 82, 68, 44, 30, 21, 13, 7, 3, 0, -1, -1, -1, -1]. Меня интересуют 107 и -1 (следующие минимумы кривой)
Но я не понимаю, код для скажем нет. кривой (итерация). ты можешь помочь мне с этим?
1 ответ
Вы можете использовать эту функцию для получения абсолютных экстремумов:
def extrema(value, deltas):
max_value = min_value = value
for delta in deltas:
value += delta
if value < min_value:
min_value = value
elif value > max_value:
max_value = value
return min_value, max_value
Здесь я адаптировал функцию для получения локальных экстремумов:
def extrema(value, deltas):
values = [value]
for delta in deltas:
value += delta
values.append(value)
average = sum(values)/len(values)
threshold = (max(values) - min(values))/6
min_threshold = average - threshold
max_threshold = average + threshold
min_value = max_value = None
for value in values:
if value < min_threshold:
if min_value is None or value < min_value:
min_value = value
elif value > max_threshold:
if max_value is None or value > max_value:
max_value = value
elif min_value is not None and max_value is not None:
yield min_value, max_value
max_value = min_value = None
Вы можете отрегулировать функцию отсюда. Например, функция может пропустить первые значения до min_threshold < value < max_threshold
найти начало цикла, и в конце он может дать последний экстремум, если он не завершится полным циклом.
Наконец, вот функция, которая работает с точечными кортежами, как в данных вашего примера.
class Point(object):
__slots__ = ('x', 'y')
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __repr__(self):
return str((self.x, self.y))
def __iadd__(self, other):
self.x += other.x
self.y += other.y
return self
def __isub__(self, other):
self.x -= other.x
self.y -= other.y
return self
def __idiv__(self, number):
self.x /= number
self.y /= number
return self
def abs(self):
return abs(self.x) + abs(self.y)
def copy(self):
return Point(self.x, self.y)
def extrema(moves, jitter=0.1, threshold=1000, sample=16):
point = Point()
minpoint = Point()
maxpoint = Point()
average = Point()
average /= 1.0
turned = False
for move in moves:
point += move
x = point.x
if x < minpoint.x:
minpoint.x = x
elif x > maxpoint.x:
maxpoint.x = x
y = point.y
if y < minpoint.y:
minpoint.y = y
elif y > maxpoint.y:
maxpoint.y = y
delta = move.copy()
delta -= average
delta /= sample
average += delta
if average.abs() < jitter:
if point.abs() > threshold:
turned = True
elif turned:
yield minpoint, maxpoint
point = Point() # reset (calibrate)
minpoint = Point()
maxpoint = Point()
turned = False
# read data from file
moves = [Point(*map(int, move.split(',')))
for move in open('data.txt').read().split(';') if move]
# generate extrema
print list(extrema(moves))