簡體   English   中英

在pandas / numpy中實現分段函數的正確方法

[英]Correct way to implement piecewise function in pandas / numpy

我需要創建一個函數來傳遞給curve_fit 在我的例子中,函數最好定義為分段函數。

我知道以下內容不起作用,但我正在顯示它,因為它使函數的意圖清晰:

def model_a(X, x1, x2, m1, b1, m2, b2):
    '''f(x) has form m1*x + b below x1, m2*x + b2 above x2, and is
    a cubic spline between those two points.'''
    y1 = m1 * X + b1
    y2 = m2 * X + b2
    if X <= x1:
        return y1    # function is linear below x1
    if X >= x2:
        return y2    # function is linear above x2
    # use a cubic spline to interpolate between lower
    # and upper line segment
    a, b, c, d = fit_cubic(x1, y1, x2, y2, m1, m2)
    return cubic(X, a, b, c, d)

當然,問題在於X是一個熊貓系列,形式(X <= x1)評估為一系列布爾值,因此失敗的消息是“系列的真值是模糊的”。

np.piecewise()似乎是針對這種情況設計的:“無論condlist [i]為True,funclist [i](x)都用作輸出值。” 所以我嘗試了這個:

def model_b(X, x1, x2, m1, b1, m2, b2):
    def lo(x):
        return m1 * x + b1
    def hi(x):
        return m2 * x + b2
    def mid(x):
        y1 = m1 * x + b1
        y2 = m2 * x + b2
        a, b, c, d = fit_cubic(x1, y1, x2, y2, m1, m2)
        return a * x * x * x + b * x * x + c * x + d

    return np.piecewise(X, [X<=x1, X>=x2], [lo, hi, mid])

但是這次會議失敗了:

return np.piecewise(X, [X<=x1, X>=x2], [lo, hi, mid])

消息“IndexError:數組索引太多”。 我傾向於認為這是反對的事實,有在condlist兩個元素和funclist三個要素,但該文檔明確指出,在funclist額外的元素作為默認處理。

任何指導?

NumPy對np.piecewise的定義中的np.piecewise 代碼list / ndarray -centric:

# undocumented: single condition is promoted to a list of one condition
if isscalar(condlist) or (
        not isinstance(condlist[0], (list, ndarray)) and x.ndim != 0):
    condlist = [condlist]

因此,如果X是一個系列,那么condlist = [X<=x1, X>=x2]是兩個Series的列表。 由於condlist[0]既不是list也不是ndarraycondlist被“提升”為一個條件的列表:

condlist = [condlist]

由於這不是我們想要發生的,我們需要在將它傳遞給np.piecewise之前使condlist成為NumPy數組的列表:

X = X.values

例如,

import numpy as np
import pandas as pd
def model_b(X, x1, x2, m1, b1, m2, b2):
    def lo(x):
        return m1 * x + b1
    def hi(x):
        return m2 * x + b2
    def mid(x):
        y1 = m1 * x + b1
        y2 = m2 * x + b2
        # a, b, c, d = fit_cubic(x1, y1, x2, y2, m1, m2)
        a, b, c, d = 1, 2, 3, 4
        return a * x * x * x + b * x * x + c * x + d
    X = X.values
    return np.piecewise(X, [X<=x1, X>=x2], [lo, hi, mid])

X = pd.Series(np.linspace(0, 100, 100))
x1, x2, m1, b1, m2, b2 = 30, 60, 10, 5, -20, 30
f = model_b(X, x1, x2, m1, b1, m2, b2)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM