0

28 個のパラメーターを持つ物理システムをモデル化しました。シミュレーションは、約 10 個の出力パラメーターの別のリストを計算します。ここで、パラメーター空間を調査する必要があります。入力パラメーターのいくつかは一定に保ち、いくつかは複数の値を持ちます。入力構造は次のようになります。

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(1 つの値)、2 番目の軸はinput2(4 つの値) などであり、最後の軸にはすべてのデータ[input1, input2, input3, input4, input5, output1, output2, output3](5 + 3 = 8 つの値) が含まれます。この例では、説明のように整形された 4 x 10 x 8 = 320 値の配列になります。

私の質問は次のとおりです。28 個のネストされたforループを手動で記述せずに、この構造を生成してからデータを入力する (各軸を反復処理する) にはどうすればよいですか?

それとも、私のデータ構造が正しくなく、より良い解決策が存在するのでしょうか?

私は pandas を使用したソリューションを受け入れています (パラメーター名を文字列として処理できるようにしたいため)。または単純な python 辞書。ボトルネックは各シミュレーションの計算時間 (定常状態に到達する必要がある) であり、シミュレーション間に数ミリ秒を費やす余裕があるため、実行速度はそれほど重要ではありません。

また、どのパラメーターを固定し、どのパラメーターを可変にするか (およびそれらの値の数) を選択する方法にも柔軟性が必要です。

4

1 に答える 1

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")
于 2014-11-09T02:03:56.390 に答える