簡體   English   中英

列上的 Python/Pandas/PuLP 優化

[英]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']來最大化headingchoices列的總和
  • 選擇列的值取決於speedheadingratio (根據給定的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM