[英]R translation to Python
我有一些我在R中编写的代码,我想将其翻译成Python,但我是python的新手,所以需要一些帮助
R代码基本上模拟250个随机法线,然后计算排序的几何平均回报,然后计算最大缩幅,它执行10000次然后组合结果,如下所示。
mu <- 0.06
sigma <- 0.20
days <- 250
n <- 10000
v <- do.call(rbind,lapply(seq(n),function(y){
rtns <- rnorm(days,mu/days,sqrt(1/days)*sigma)
p.rtns <- cumprod(rtns+1)
p.rtns.md <- min((p.rtns/cummax(c(1,p.rtns))[-1])-1)
tot.rtn <- p.rtns[days]-1
c(tot.rtn,p.rtns.md)
}))
这是我在Python中的尝试,(如果你可以让它更短/更有说服力/更高效请建议作为答案)
import numpy as np
import pandas as pd
mu = float(0.06)
sigma = float(0.2)
days = float(250)
n = 10000
rtns = np.random.normal(loc=mu/days,scale=(((1/days)**0.5)*sigma),size=days)
rtns1 = rtns+1
prtns = rtns1.cumprod()
totrtn = prtns[len(prtns)-1] -1
h = prtns.tolist()
h.insert(0,float(1))
hdf = pd.DataFrame(prtns)/(pd.DataFrame(h).cummax()[1:len(h)]-1))[1:len(h)]]
这就是我得到的...不太确定hdf
是否正确得到p.rtns.md
,并且不确定我将如何模拟这10000次。
所有建议将不胜感激......
我不熟悉R,但我看到可以对Python代码进行一些一般性的改进:
0.06
不带float()
,因为Python会推断带小数点的数值是float
h.insert(0,float(1))
可以替换为h.insert(0,1.0)
[-1]
引用可迭代中的最后一项,使用[-2]
引用倒数第二项,等等:
totrtn = prtns[-1] -1
Python开发人员通常会在单词或camelcase之间选择下划线。 此外,通常最好使用变量名中的完整单词,以便在屏幕上显示经济性。 例如,这里的一些变量可以重命名为returns
和total_returns
或totalReturns
。
要运行模拟10000次,您应该使用for
循环:
for i in range(10000):
# code to be repeated 10000 goes in an indented block here
# more lines in the loop should be indented at same level as previous line
# to mark what code runs after the for loop finishes, just un-indent again
h - prtns.tolist()
...
首先,你的最后一行代码:
hdf = pd.DataFrame(prtns)/(pd.DataFrame(h).cummax()[1:len(h)]-1))[1:len(h)]]
不可能是对的。 可能是根据你的R
代码:
hdf = (pd.DataFrame(prtns)/(pd.DataFrame(h).cummax()[1:len(h)])-1)[1:len(h)]
其次, c(1,p.rtns)
可以用np.hstack(1, prtns)
替换,而不是将np.array
转换为list
。
第三,看起来你只是为了cummax()
使用pandas
。 实现一个并不难,就像这样:
def cummax(a):
ac=a.copy()
if a.size>0:
max_idx=np.argmax(a)
ac[max_idx:]=np.max(ac)
ac[:max_idx]=cummax(ac[:max_idx])
else:
pass
return ac
和:
>>> a=np.random.randint(0,20,size=10)
>>> a
array([15, 15, 15, 8, 5, 14, 6, 18, 9, 1])
>>> cummax(a)
array([15, 15, 15, 15, 15, 15, 15, 18, 18, 18])
把这些全部放在一起得到:
def run_simulation(mu, sigma, days, n):
result=[]
for i in range(n):
rtns = np.random.normal(loc=1.*mu/days,
scale=(((1./days)**0.5)*sigma),
size=days)
p_rtns = (rtns+1).cumprod()
tot_rtn = p_rtns[-1]-1
#looks like you want the last element, rather than the 2nd form the last as you did
p_rtns_md =(p_rtns/cummax(np.hstack((0.,p_rtns)))[1:]-1).min()
#looks like you want to skip the first element, python is different from R for that.
result.append((tot_rtn, p_rtns_md))
return result
和:
>>> run_simulation(0.06, 0.2, 250,10)
[(0.096077511394818016, -0.16621830496112056), (0.73729333554192, -0.13566124517484235), (0.087761655465907973, -0.17862916081223446), (0.07434851091082928, -0.15972961033789046), (-0.094464694393288307, -0.2317397117033817), (-0.090720761054686627, -0.1454002204893271), (0.02221364097529932, -0.15606214341947877), (-0.12362835704696629, -0.24323096421682033), (0.023089144896788261, -0.16916790589553599), (0.39777037782177493, -0.10524624505023494)]
实际上没有必要使用循环,因为我们可以通过生成高斯随机变量的二维array
(改变size=days
到size=(days, n)
)来二维工作。 避免循环很可能会更快。 但是,这将需要一个不同的cummax()
函数,因为这里显示的限制为1D。 但是R
cummax()
被限制为1D(不完全是,如果你将2D传递给cummax()
,它将被展平)。 因此,为了保持Python
和R
之间的简单和可比性,让我们选择循环版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.