Пошаговая линейная функция из серии Pandas - PullRequest
1 голос
/ 05 февраля 2020

У меня есть много больших Pandas рядов "наклонов стоимости", представляющих линейную функцию f, приведенную в болезненной форме. Вот гораздо меньший пример:

slopes = Series({'-inf': 10, -200: 60, 0: 0, 200: 1, 'inf': 10})

-inf    10
-200    60
0        0
200      1
inf     10

(0, 0) всегда в Серии, а уклоны представляют кусочно «предельные издержки», когда вы двигаетесь от нуля в любом направлении

f(-200) = 12000  # abs(-200) * 60
f(-100) = 6000  # abs(-100) * 60
f(0) = 0
f(100) = 100  # 100 * 1
f(200) = 200  # 200 * 1
f(300) = 1200  # 200 * 1 + (300-200) * 10

поскольку серии большие и их многократно называют, я надеялся поместить это в форму, в которой я могу использовать Numpy s interp или piecewise или Pandas interpolate для скорости, а не для построения for loop.

Я думаю, piecewise может быть решением, но я не уверен, как преобразовать и обработать inf? Может быть, есть более чистый способ?

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Выбирая использование np.piecewise, вам просто нужно указать интервалы наклона стоимости как condlist и соответствующие выражения линейной функции как funclist, например:

import numpy as np
import matplotlib.pyplot as plt

x = np.array([-200,-100,0,100,200,300])

condlist = [x<-200,\
            np.logical_and(x>=-200, x<0),\
            x==0,\
            np.logical_and(x>0,x<=200),\
            x>200]
funclist = [lambda x: 200*60+abs(x+200)*10,\
            lambda x: abs(x)*60,\
            lambda x:0,\
            lambda x: abs(x)*1,\
            lambda x: 200*1+abs(x-200)*10]

f = np.piecewise(x,condlist,funclist)

проверка правильности реализации с заданным очков, это следует:

np.allclose([12000,6000,0,100,200,1200],f)
>>> True

, которая построена для большего диапазона, скажем, x = np.linspace(-500,500,2000), в итоге дает:

plt.plot(x, f,'r')
plt.scatter([-200,-100,0,100,200,300],[12000,6000,0,100,200,1200],s=20,zorder=5)

piecewise_output

Надеюсь, это поможет.

0 голосов
/ 06 февраля 2020
import math
slopes = pd.Series({ -math.inf: 10, -200: 60, 0: 0, 200: 1, 300: 10, math.inf: 10})

Определите свою функцию стоимости, как вы будете sh

def cost_func(x):
    if x[0] < 200:
        return abs(x[0]) * x[1]
    else: 
        return 200 + abs(x[0]-200) * x[1]

slope_df = pd.DataFrame({'value':slopes.index, 'amount':slopes.values}, index = range(slopes.size))

slope_df['cost'] = slope_df[ ['value', 'amount'] ].apply(lambda row: cost_func(row), axis=1)
print(slope_df)

slope_df output

...