2014-11-08 22 views
0

我用28個參數建模了一個物理系統。該模擬計算約10個輸出參數的另一個列表。現在我需要探索參數空間:我保持不變的一些輸入參數,有些參數有多個值。輸入結構是這樣的:如何準備,填充和探索n維numpy數組?

input_params = { 
    'input1': [0.3], # fixed 
    'input2': [1.5, 4.5, 4], # variable param: [start, end, number_of_intermediate_values] 
    'input3': [1200.0], # fixed 
    'input4': [-0.1, -0.5, 10], # variable param: [start, end, number_of_intermediate_values] 
    'input5': [1e-3], # fixed 
} 

模擬程序的輸出是這樣的(用於輸入的組合):

output_params = { 
    'output1': 3.9, 
    'output2': -2.5, 
    'output3': 100.0, 
} 

我想生成的n維陣列,使得我可以在最大限度的靈活性之後進行探索。對於上面的例子,應該是這樣的數組:

results = np.zeros(shape=(1,4,1,10,1,8)) 

其中第一軸是input1(一個值),爲input2(四個值)的第二軸線等,最後軸包含所有數據[input1, input2, input3, input4, input5, output1, output2, output3](5 + 3 = 8個值)。對於這個例子,它將是一個4×10×8 = 320的數組,如上所述。

我的問題是:我怎樣才能生成這個結構,然後填充它(遍歷每個軸)而不用手寫28嵌套for循環?

或者,也許我的數據結構不正確,存在更好的解決方案?

我打開使用熊貓的解決方案(因爲我想能夠將參數名稱作爲字符串處理)。或簡單的python字典。執行速度並不那麼重要,因爲瓶頸是每次模擬的計算時間(它需要達到穩定狀態),我可以在模擬之間花費幾個毫秒。

我還需要靈活性來選擇哪些參數是固定的,哪些是可變的(以及它們有多少個值)。

回答

1

生成所有輸入模式,您可以使用:pd.MultiIndex.from_product()

下面是代碼:

import numpy as np 
import pandas as pd 

input_params = { 
    'input1': [0.3], # fixed 
    'input2': [1.5, 4.5, 4], # variable param: [start, end, number_of_intermediate_values] 
    'input3': [1200.0], # fixed 
    'input4': [-0.1, -0.5, 10], # variable param: [start, end, number_of_intermediate_values] 
    'input5': [1e-3], # fixed 
} 

def expand_input(inputs): 
    if len(inputs) == 1: 
     return inputs 
    return np.linspace(*inputs).tolist() 

def sim(in_pars): 
    "dummy simulation that returns three results" 
    return np.min(in_pars), np.mean(in_pars), np.max(in_pars) 

items = sorted(input_params.items()) 
keys = [item[0] for item in items] 
inputs = [expand_input(item[1]) for item in items] 

idx = pd.MultiIndex.from_product(inputs, names=keys) 
df = pd.DataFrame(np.zeros((len(idx), 3)), columns="res1 res2 res3".split(), index=idx) 

for key, row in df.iterrows(): 
    row[:] = sim(key) 

print df 

輸出:

          res1  res2 res3 
input1 input2 input3 input4 input5        
0.3 1.5 1200 -0.100000 0.001 -0.100000 240.340200 1200 
        -0.144444 0.001 -0.144444 240.331311 1200 
        -0.188889 0.001 -0.188889 240.322422 1200 
        -0.233333 0.001 -0.233333 240.313533 1200 
        -0.277778 0.001 -0.277778 240.304644 1200 
        -0.322222 0.001 -0.322222 240.295756 1200 
        -0.366667 0.001 -0.366667 240.286867 1200 
        -0.411111 0.001 -0.411111 240.277978 1200 
        -0.455556 0.001 -0.455556 240.269089 1200 
        -0.500000 0.001 -0.500000 240.260200 1200 
     2.5 1200 -0.100000 0.001 -0.100000 240.540200 1200 
        -0.144444 0.001 -0.144444 240.531311 1200 
        -0.188889 0.001 -0.188889 240.522422 1200 
        -0.233333 0.001 -0.233333 240.513533 1200 
        -0.277778 0.001 -0.277778 240.504644 1200 
        -0.322222 0.001 -0.322222 240.495756 1200 
        -0.366667 0.001 -0.366667 240.486867 1200 
        -0.411111 0.001 -0.411111 240.477978 1200 
        -0.455556 0.001 -0.455556 240.469089 1200 
        -0.500000 0.001 -0.500000 240.460200 1200 
     3.5 1200 -0.100000 0.001 -0.100000 240.740200 1200 
        -0.144444 0.001 -0.144444 240.731311 1200 
        -0.188889 0.001 -0.188889 240.722422 1200 
        -0.233333 0.001 -0.233333 240.713533 1200 
        -0.277778 0.001 -0.277778 240.704644 1200 
        -0.322222 0.001 -0.322222 240.695756 1200 
        -0.366667 0.001 -0.366667 240.686867 1200 
        -0.411111 0.001 -0.411111 240.677978 1200 
        -0.455556 0.001 -0.455556 240.669089 1200 
        -0.500000 0.001 -0.500000 240.660200 1200 
     4.5 1200 -0.100000 0.001 -0.100000 240.940200 1200 
        -0.144444 0.001 -0.144444 240.931311 1200 
        -0.188889 0.001 -0.188889 240.922422 1200 
        -0.233333 0.001 -0.233333 240.913533 1200 
        -0.277778 0.001 -0.277778 240.904644 1200 
        -0.322222 0.001 -0.322222 240.895756 1200 
        -0.366667 0.001 -0.366667 240.886867 1200 
        -0.411111 0.001 -0.411111 240.877978 1200 
        -0.455556 0.001 -0.455556 240.869089 1200 
        -0.500000 0.001 -0.500000 240.860200 1200 

如果有這麼多的輸入模式,我認爲將所有結果保存在內存中並不是一個好主意,您可以將結果保存到文件中:

from itertools import product 

with open("result.txt", "w") as f: 
    for in_pars in product(*inputs): 
     res = sim(in_pars) 
     f.write(",".join(str(x) for x in in_pars + res)) 
     f.write("\n") 
+0

哇!這似乎是我需要的。我將在測試提出的解決方案後回來。謝謝。 – Amenhotep 2014-11-09 13:30:56

+0

我開始實施這個解決方案。在'for key,row in df.iterrows():row [:] = sim(key)'中,如何通過名稱訪問輸入參數?他們是28,我討厭記得數字索引... – Amenhotep 2014-11-09 17:37:57

+0

另一個問題:行'items = sorted(input_params.items())'是強制性的?是否因爲multiindex只有在排序後才起作用? – Amenhotep 2014-11-09 17:45:59