Python 中曲线的最大值和最小值点

发布于 2024-12-18 09:11:51 字数 449 浏览 1 评论 0原文

我从位移传感器捕获了数据,一次迭代的增量值如下所示。 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 (下一个曲线最小值)感兴趣,

但我不知道说 n 不的代码。曲线(迭代)。你能帮我解决这个问题吗?

I have a captured a data from a displacement sensor, the delta values for one iteration look like this. 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. (other iterations are also have same pattern.)

I am interested in the maxima and minima points of a curves. I start with a initial position and come back to this position for a loops for line(I've take the partial sum of the values to get the total displacement or line). The partial sum look like this [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]. I am interested in 107 and -1 (the next curve minima)

But I am not figure out the code for say n no. of curve (iteration). Can you help me with this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ぃ双果 2024-12-25 09:11:51

您可以使用此函数来获取绝对极值:

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 值< 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))

You can use this function for getting the absolute extrema:

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

Here I have adapted the function to yield local extrema:

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

You can fine-tune the function from here. For instance, the function could skip the first values until min_threshold < value < max_threshold to find the start of a cycle, and at the end it could yield the last extremum if it did not end with a full cycle.

Lastly, here is a function that works with point tuples as in your example data.

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))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文