[英]How to prepare, populate and explore an n-dimensional numpy array?
我已經用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
(一個值),對於第二軸input2
(四個值)等等,最后軸線包含了所有的數據[input1, input2, input3, input4, input5, output1, output2, output3]
(5 + 3 = 8個值)。 對於此示例,將是如所述的形狀為4 x 10 x 8 = 320值的數組。
我的問題是:如何生成此結構,然后填充它(在每個軸上迭代)而無需手動編寫28個嵌套的for
循環?
還是我的數據結構不正確,並且存在更好的解決方案?
我願意使用熊貓解決方案(因為我希望能夠將參數名稱作為字符串來處理)。 或簡單的python字典。 執行速度不是那么重要,因為瓶頸是每次模擬的計算時間(需要達到穩定狀態),我可以承受兩次模擬之間的幾毫秒的花費。
我還需要靈活地選擇固定的參數和可變的參數(以及它們具有多少個值)。
要生成所有輸入模式,可以使用: 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")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.