2015-12-15 30 views
0

我有一個名爲「cmp_twtt_amp_rho」的輸入文件,它的長度爲7795074行。 我想計算每行的聲速c,其中:Python:加快緩慢的循環計算(np.append)

c(i)= rho(i-1)* c(i-1)*( - 1- amp(i))/ rho (i)*(amp(i)-1)

使用初始猜測c = 1450。

我寫了一個for循環,我相信會的工作,但它得到增加與時間慢,以至於是不可設想的運行在它的當前格式。

有人可以幫我加快這段代碼嗎?

data=np.genfromtxt('./cmp_twtt_amp_rho') 
cmp_no=data[:,[0]] 
twtt=data[:,[1]] 
amp=data[:,[2]] 
rho=data[:,[3]] 

cs=[] 

for i in range(1,len(amp-1)): 
    if i == 1: 
    print "Using an initial guess of 1450 m/s" 
    c = (rho[i-1]*1450*(-1-amp[i]))/(rho[i]*(1-amp[i])) 
    cs = np.append(c,cs) 
    elif twtt[i] == 0: 
    print "Reached new cmp #: ",cmp_no[i],"as twwt has re-started at ",twtt[i] 
    c = 1450 
    cs = np.append(c,cs) 
    else: 
    print i 
    c = (rho[i-1]*cs[i-1]*(-1-amp[i]))/(rho[i]*(1-amp[i])) 
    cs = np.append(c,cs) 

print min(cs), max(cs) 
print len(cs) 
+0

如果您只是執行'cs.append(c)'而不是'cs = np.append(c,cs)',會發生什麼? – mgilson

+0

您有符號錯誤。您帖子中的公式與代碼不匹配;公式表示爲'(amp(i) - 1)',代碼表示爲'(1 - amp [i])'。 – user2357112

+0

道歉,代碼中的一種類型,公式是正確的。 – Kg123

回答

0

np.append已重新分配整個數組,巫婆是壞的,但並不是唯一的問題。要附加到csc不是周圍的其他方式,這意味着cs將會反轉,cs[i-1]實際上是第一c

這是一般更好地預先分配您的陣列:

cs = np.zeros(len(amp-1)) 

然後就直接設置值:

cs[i] = c 

像這樣的東西應該是有點快:

cs=np.zeros(len(amp-1)) 

print "Using an initial guess of 1450 m/s" 
cs[1] = (rho[i-1]*1450*(-1-amp[i]))/(rho[i]*(1-amp[i])) 

for i in range(2,len(amp-1)): 
    if twtt[i] == 0: 
    print "Reached new cmp #: ",cmp_no[i],"as twwt has re-started at ",twtt[i] 
    cs[i] = 1450 
    else: 
    print i 
    cs[i] = (rho[i-1]*cs[i-1]*(-1-amp[i]))/(rho[i]*(1-amp[i])) 
+0

謝謝。這顯着加快了速度。 – Kg123

+0

乾杯,請考慮user2357112的解決方案,它會更快。 – pseudoDust

1

numpy的陣列不是真的意味着被所附(numpy的需要每次分配一個完整的新的數組,並在複製舊數據)。你可能不希望在循環中這樣做。

最好使用這種數據結構 - 通常python的list處理附加得很好,所以我建議你將數據存儲在一個列表中,並在你去時追加它。然後最後,如果您需要將完整的數據集作爲數組,則可以在該點處進行轉換。

我建議只是改變以cs.append(c),而不是cs = np.append(c, cs)

+0

這引起了一個問題,在最後的「其他」條件: 該代碼是不滿意的c =(rho [i-1] * cs [i-1] *( - 1-Z [i]))/ (rho [i] *(Z [i] -1)) 並給出以下錯誤:「IndexError:列表索引超出範圍」。我不知道它爲什麼給出索引錯誤? 我最初用cs = []設置cs,但我不認爲這是問題? – Kg123

2

追加到數組非常慢,因爲您必須每次都分配一個全新的數組。在循環中執行它總是會導致性能下降。

而是附加在一個循環中,甚至使用Python的水平環可言的,你可以得到這個更快地完成與矢量運算和累積產品:

multipliers = rho[:-1] * (-1 - amp[1:])/(rho[1:] * (1 - amp[1:]) 
cs = np.cumprod(np.insert(multipliers, 0, 1450)) 

insert也需要分配的整個新陣列,但沒關係,因爲我們只做了一次。)

此外,您可能有一個符號錯誤。您的公式爲(amp(i) - 1),代碼爲(1 - amp[i])。我已選擇匹配您的代碼,但您可能需要更正此問題。