[英]Python / Pandas / PuLP optimization on a column
我正在嘗試優化 Pandas 數據框中的一列數據。 我瀏覽了過去的帖子,但找不到解決優化數據框中列中值的問題的帖子。 這是我的第一篇文章,對編碼相對較新,因此請提前道歉。 下面是我正在使用的代碼
from pandas import DataFrame
import numpy as np
from pulp import *
heading = [184, 153, 140, 122, 119]
df = DataFrame (heading, columns=['heading'])
df['speed'] = 50
df['ratio'] = df.speed/df.heading
conditions = [
(df['ratio'] < 0.1),
(df['ratio'] >= 0.1 ) & (df['ratio'] < 0.2),
(df['ratio'] >= 0.2 ) & (df['ratio'] < 0.3),
(df['ratio'] >= 0.3 ) & (df['ratio'] < 0.4),
(df['ratio'] > 0.4 )]
choices = [3, 1, 8, 5, 2]
df['choice'] = np.select(conditions, choices)
df['final_column'] = df.choice * df.heading
print(np.sum(df.final_column))
我使用 np.select 搜索“條件”並返回適當的“選擇”。 這就像我在 excel 中使用的 vlookup 一樣。
我正在嘗試使用 PuLP 或任何其他適當的優化工具,甚至可能只是一個循環來找到 df.speed 的最佳值(我從臨時值 50 開始)以最大化“final_column”中的值的總和。 下面是我試過的代碼,但它不起作用。
prob = LpProblem("Optimal Values",LpMaximize)
speed_vars = LpVariable("Variable",df.speed,lowBound=0,cat='Integer')
prob += lpSum(df.new_column_final)
prob.solve()
下面是我得到的錯誤:
speed_vars = LpVariable("Variable",df.speed,lowBound=0,cat='Integer') TypeError: init () 得到了多個參數“lowBound”的值
非常感謝你的幫助。 任何幫助,將不勝感激!
首先,您收到的具體錯誤消息是: TypeError: __init__() got multiple values for argument 'lowBound'
在python中調用函數時,您可以通過“位置”傳遞參數 - 這意味着傳遞參數的順序告訴函數每個參數是什么 - 或者通過命名它們。 如果您查找紙漿.LpVariable 方法的文檔,您會看到第二個位置參數是'lowbound'
,然后您也將其作為命名參數傳遞 - 因此出現錯誤消息。
我認為您也可能對數據框的工作方式略有誤解。 它不像在列中設置“公式”的 excel 那樣,它會隨着該行上的其他元素更改而保持更新到該公式。 您可以為列分配值,但如果輸入數據發生更改 - 只有再次運行該位代碼時才會更新單元格。
在解決您的問題方面 - 我不相信我已經理解你想要做什么,但我已經理解了以下內容。
df['speed']
來最大化heading
和choices
列的總和speed
與heading
的ratio
(根據給定的 5 個范圍)Heading
欄是固定的通過檢查,將通過設置所有速度使比率在 [0.2 - 0.3] 范圍內來實現最佳,並且它們在該范圍內的位置無關緊要。 在下面的 Pandas 數據框中的 PuLP 中執行此操作的代碼。 它依賴於使用二進制變量來跟蹤比率落在哪個范圍內。
雖然語法有點笨拙 - 我建議完全在數據幀之外進行優化,並在最后加載結果 - 使用LpVariable.dicts
方法來創建變量數組。
from pandas import DataFrame
import numpy as np
from pulp import *
headings = [184.0, 153.0, 140.0, 122.0, 119.0]
df = DataFrame (headings, columns=['heading'])
df['speed'] = 50
max_speed = 500.0
max_ratio = max_speed / np.min(headings)
df['ratio'] = df.speed/df.heading
conditions_lb = [0, 0.1, 0.2, 0.3, 0.4]
conditions_ub = [0.1, 0.2, 0.3, 0.4, max_speed / np.min(headings)]
choices = [3, 1, 8, 5, 2]
n_range = len(choices)
n_rows = len(df)
# Create primary ratio variables - one for each variable:
df['speed_vars'] = [LpVariable("speed_"+str(j)) for j in range(n_rows)]
# Create auxilary variables - binaries to control
# which bit of range each speed is in
df['aux_vars'] = [[LpVariable("aux_"+str(i)+"_"+str(j), cat='Binary')
for i in range(n_range)]
for j in range(n_rows)]
# Declare problem
prob = LpProblem("max_pd_column",LpMaximize)
# Define objective function
prob += lpSum([df['aux_vars'][j][i]*choices[i]*headings[j] for i in range(n_range)
for j in range(n_rows)])
# Constrain only one range to be selected for each row
for j in range(n_rows):
prob += lpSum([df['aux_vars'][j][i] for i in range(n_range)]) == 1
# Constrain the value of the speed by the ratio range selected
for j in range(n_rows):
for i in range(n_range):
prob += df['speed_vars'][j]*(1.0/df['heading'][j]) <= \
conditions_ub[i] + (1-df['aux_vars'][j][i])*max_ratio
prob += df['speed_vars'][j]*(1.0/df['heading'][j]) >= \
conditions_lb[i]*df['aux_vars'][j][i]
# Solve problem and print results
prob.solve()
# Dislay the optimums of each var in problem
for v in prob.variables ():
print (v.name, "=", v.varValue)
# Set values in dataframe and print:
df['speed_opt'] = [df['speed_vars'][j].varValue for j in range(n_rows)]
df['ratio_opt'] = df.speed_opt/df.heading
print(df)
最后一點打印出來:
heading speed_vars b spd_opt rat_opt
0 184.0 speed_0 [b_0_0, b_1_0, b_2_0, b_3_0, b_4_0] 36.8 0.2
1 153.0 speed_1 [b_0_1, b_1_1, b_2_1, b_3_1, b_4_1] 30.6 0.2
2 140.0 speed_2 [b_0_2, b_1_2, b_2_2, b_3_2, b_4_2] 28.0 0.2
3 122.0 speed_3 [b_0_3, b_1_3, b_2_3, b_3_3, b_4_3] 24.4 0.2
4 119.0 speed_4 [b_0_4, b_1_4, b_2_4, b_3_4, b_4_4] 23.8 0.2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.