簡體   English   中英

R轉換為Python

[英]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之間選擇下划線。 此外,通常最好使用變量名中的完整單詞,以便在屏幕上顯示經濟性。 例如,這里的一些變量可以重命名為returnstotal_returnstotalReturns

要運行模擬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=dayssize=(days, n) )來二維工作。 避免循環很可能會更快。 但是,這將需要一個不同的cummax()函數,因為這里顯示的限制為1D。 但是R cummax()被限制為1D(不完全是,如果你將2D傳遞給cummax() ,它將被展平)。 因此,為了保持PythonR之間的簡單和可比性,讓我們選擇循環版本。

暫無
暫無

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

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