2017-03-02 87 views
1

我想向矩陣中添加更多的數據來分析和解決問題,但是因爲它目前正在執行粗暴操作,所以如果我在分析中添加另一列,則會超出python的極限。有沒有解決方法可以找到類似的結果,而不是不得不通過組合來暴力行爲? sample.csv也在下面列出。感謝您的任何建議。Python,求解器方法還是當前代碼的優化?

import csv 
import itertools as it 
import numpy as np 

C = 2618.08 
B = 933.15 
A = 932.37 
adjust = 1 


D = csv.reader(open('sample.csv')) 

float_ABC = [] 
OUT = np.zeros((3, 9)) - 100 

for row in D: 
     float_ABC.append([str(x) for x in row]) 

float_ABC = float_ABC.astype(np.float) 

Alpha=float_ABC[:, [0,3,6,9,12,15]] 
Beta=float_ABC[:, [2,5,8,11,14,17]] 
Phi=float_ABC[:, [1,4,7,10,13,16]] 

plines1 = it.product(Alpha[0],Alpha[1],Alpha[2],Alpha[3], 
        Alpha[4],Alpha[5],Alpha[6],Alpha[7], 
        Alpha[8]) 

plines2 = it.product(Beta[0],Beta[1],Beta[2],Beta[3], 
        Beta[4],Beta[5],Beta[6],Beta[7], 
        Beta[8]) 

plines3 = it.product(Phi[0],Phi[1],Phi[2],Phi[3], 
        Phi[4],Phi[5],Phi[6],Phi[7], 
        Phi[8]) 


for count in range(0,6**9): 
    sumA = next(plines1) 
    sumB = next(plines2) 
    sumC = next(plines3) 

    if (sum(sumC)+B)/(sum(sumA)+C) <= (B+adjust)/(C) and \ 
     (sum(sumC)+B)/(sum(sumA)+C) >= (B+adjust-10)/(C) and \ 
     (sum(sumB)+A)/(sum(sumA)+C) > (sum(OUT[2])+A)/(sum(OUT[0])+C): 
     print("#",count,"- new option found!") 
     OUT = np.vstack((sumA,sumC,sumB)) 

和sample.csv:

13.4,-18.81,-24.75,5.82,-8.21,-10.8,0,0,0,3.3,1.56,2.05,-2.1,5.36,7.05,2.6,5.65,7.44 
0,-11.01,-14.49,0,-4.87,-6.41,0,0,0,0.6,2.24,2.95,1,4,5.26,1.7,2.73,3.59 
0,-40.74,-53.6,0,-17.86,-23.5,0,0,0,3.5,6.53,8.59,2.9,9.36,12.31,1.9,2.61,3.44 
1000,-1000,-1000,0,0,0,20.76,21.78,15.66,18.48,23.44,16.96,27.72,26.46,19.92,32.28,29.58,23.08 
1000,-1000,-1000,-2.28,-6.12,-4.16,-2.28,-2.53,-1.73,0,0,0,1.92,-1.85,-1.26,1.08,-1.27,-0.86 
1000,-1000,-1000,0,0,0,6.78,7.38,5.07,6.66,8.93,6.14,8.46,8.41,5.78,9.42,10.37,7.14 
1000,-1000,-1000,0,0,0,28.8,34.28,27.86,37.2,39.64,33.32,45.6,42.76,36.63,54,45.88,40.03 
1000,-1000,-1000,0,-4.95,-3.36,0,0,0,1.8,0.59,0.4,1.2,1.85,1.27,3.72,0.17,0.11 
1000,-1000,-1000,0,0,0,27.6,19.3,13.71,32.76,23.68,17.15,37.8,20.56,14.71,22.56,27.58,21.06 
+1

什麼叫「超過Python的限制」是什麼意思?你得到什麼樣的錯誤?我可以建議在枚舉(zip(plines1,plines2,plines3))中使用'for count(sumA,sumB,sumC):'並緩存'sum(sumA)+ C'的結果等等,因爲你重新計算了幾次每一次迭代。 –

+1

我期望上面的代碼引發'AttributeError:'列表'對象沒有屬性'astype''行'float_ABC = float_ABC.astype(np.float)'因爲'float_ABC'是一個列表... –

+0

謝謝@ TadhgMcDonald-Jensen輸入 - count中的行(sumA,sumB,sumC)在枚舉中(zip(plines1,plines2,plines3)):'由於某種原因沒有連接在我的大腦中,我曾經使用過在我分析的其他部分 - 這確實有道理。對於float_ABC行來說,它已經將一些條目作爲字符串來處理,因此它將所有條目都轉換爲浮動對象 - 似乎在我的最後工作得很好。非常感謝您的幫助! –

回答

0

這個答案是處理這個問題更像codereview然後用算法幫助。

首先,你可以iterate over all three plines1 at the same time using zip

for sumA, sumB, sumC in zip(plines1, plines2, plines3): 
    pass 

但隨後拿到步驟的運行計數你是你可以使用enumerate

for count, (sumA, sumB, sumC) in enumerate(zip(plines1, plines2, plines3)): 
    pass 

我也注意到你重新計算(B+adjust)/(C)(B+adjust-10)/(C)每次迭代根本沒有在循環中改變,所以在循環之前計算一次,而不是每次迭代都會節省一些執行時間:

high_check = (B+adjust)/(C) 
low_check = (B+adjust-10)/(C) 

for count, (sumA, sumB, sumC) in enumerate(zip(plines1, plines2, plines3)): 

    if (low_check <= (sum(sumC)+B)/(sum(sumA)+C) <= high_check 
      and <OTHER CHECK>): 
     ... 

以及計算sum(sumA)(和sumB,sumC)一遍又一遍地是unecessarily昂貴,而且有些混亂,因爲sumA代表值的元組,它會更有意義,一旦計算的款項,並採取元組(sumA, sumB, sumC)如稱爲matrix一個值(第2元組是足夠接近)

for count, matrix in enumerate(zip(plines1, plines2, plines3)): 
    sumA, sumB, sumC = map(sum, matrix) 
    if (low_check <= (sumC+B)/(sumA+C) <= high_check 
      and <OTHER CHECK>): 
     ... 
     OUT = np.vstack(matrix) 

同樣僅重新計算(sum(OUT[2])+A)/(sum(OUT[0])+C)只有當OUT變化將減少重新計算不變值所需的執行時間:

OUT_check = (sum(OUT[2])+A)/(sum(OUT[0])+C) 

for ... in ...: 

    if ( ... 
      and (sumB+A)/(sumA+C) > OUT_check): 
     ... 
     OUT_check = (sum(OUT[2])+A)/(sum(OUT[0])+C) 

這樣的改變代碼段是這樣的:

plines1 = it.product(*Alpha) #star notation just unpacks all the elements into arguments 
plines2 = it.product(*Beta) 
plines3 = it.product(*Phi) 

high_check = (B+adjust)/(C) 
low_check = (B+adjust-10)/(C) 
OUT_check = (sum(OUT[2])+A)/(sum(OUT[0])+C) 

for count, matrix in enumerate(zip(plines1, plines2, plines3)): 
    sumA, sumB, sumC = map(sum, matrix) 
    if (low_check <= (sumC+B)/(sumA+C) <= high_check 
      and (sumB+A)/(sumA+C) > OUT_check): 
     print("#",count,"- new option found!") 
     OUT = np.vstack(matrix) 
     OUT_check = (sum(OUT[2])+A)/(sum(OUT[0])+C) 
+0

我已經更改了代碼以枚舉和緩存我可以使用的部分,並在給定當前算法的情況下節省了一些計算時間。我感謝當前算法的優化。我想我要求進一步提高時間 - 是否有解算器算法可以進一步提高時間,以便我可以添加更多列的數據進行分析?我的最終目標是讓sample.csv將15個項目導入每個元組,而不是9個。我是否能夠在'scipy'算法的幫助下實現此目標。在遍歷所有plines之前優化'? –

+0

我還沒有真正使用過這些功能,所以我不能在這方面提供幫助,對不起。 –