使用fsolve查找两个平均值在Python中相交所需的价格

时间:2018-08-04 22:43:50

标签: python pandas scipy

我正在尝试在Python中创建一个函数,以解决两个不同长度的数据集上两个移动平均值所需要的值相等。例如,数据集

5
2
34
54
5
Average = 14

7
4
11
5
56
7
8
Average = 20

我想求解一些X,使它们都等于相同的平均值。我相信scipy中的fsolve函数可以轻松地做到这一点,但是要注意的是,我想使用类似于熊猫的.rolling函数的方法来做到这一点,因此该公式可以应用于滚动数据集遍历数千行数据。

因此,我正在设想类似以下的功能,尽管显然它不起作用。为了明确起见,count_变量的值为+ 1,因为我只想查看一个跟踪数据集,该数据集是我要查找的实际平均集的-1。非常感谢您的帮助,谢谢!

def equations(short_ma, long_ma, p):
    sum_short = short_ma.sum()
    sum_long = long_ma.sum()
    count_short = short_ma.count() + 1
    count_long = long_ma.count() + 1
    ptv, eq_var = p
    return (((sum_short + ptv) / count_short) - eq_var, ((sum_long + ptv) / count_long) - eq_var)

def rolling_equations(ptv, eq_var):
    ptv, eq_var = fsolve(equations, (1,1))
    return ptv

2 个答案:

答案 0 :(得分:1)

您不需要数值求解器来求解一个变量的一个线性方程(同样,如果它是线性方程组,则应使用linalg,但它仅从两个方程开始)。如果你想

(a.sum()+eqVar)/(a.size+1) == (b.sum()+eqVar)/(b.size+1)

然后

eqVar == (b.sum()/(b.size()+1)-a.sum()/(a.size+1))/(1/(a.size+1)-1/(b.size+1)) ==
      == (b.sum()/(b.size()+1)-a.sum()/(a.size+1))*((a.size+1)(b.size+1)/(a.size-b.size)) ==
      == ((a.size+1)*b.sum()-(b.size+1)*a.sum())/(a.size-b.size)

如果我没有弄错我的数学。为了简化起见,假设您只想在第一列中添加一个值以使其等同(您可以仔细检查并使用上面的值):

import numpy  as np
import pandas as pd

def eqVar(df):
    a = df[0] 
    b = df[1] 
    return b.sum()*(a.size+1)/b.size-a.sum()

df = pd.DataFrame(np.random.random(20).reshape(-1,2))
df.rolling(4).apply(eqVar)

您可以使用其中一行来简化说明

df.rolling(4).apply(lambda d: d[1].sum()*(d[0].size+1)/d[1].size-d[0].sum())

答案 1 :(得分:1)

这就是我最终要做的事情,实际上是根据@kabanus的建议进行建模的。请注意,我还有另一个名为arguments1的模块,该模块可以导入变量。

import pandas as pd
import numpy as np
from arguments1 import *

def common_value_solver(range):
    short_ma = arguments1.short_ma
    long_ma = arguments1.long_ma
    sum_short = range.tail(short_ma-1).sum()
    sum_long = range.tail(long_ma-1).sum()
    count_short = short_ma_arg
    count_long = long_ma_arg
    ptv = ((count_long * sum_short) - (count_short * sum_long) / (count_short - count_long))
    return ptv