You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

循环中无法为Pandas DataFrame新列正确赋值的问题排查

问题

无法在循环中为Pandas DataFrame的新列正确赋值。程序整体运行正常,仅一行代码异常——需要将原始DataFrame的行追加到Feasible_Distribution_Plan后,给这个新DataFrame添加Distance to Site Location列,存储每次选中的Warehouse对应的仓库到站点的距离,但当前代码实现不了。


相关代码

原始DataFrame定义

import pandas as pd

df = pd.DataFrame({
    'Name': {0: 'a', 1: 'c', 2: 'j', 3: 'd', 4: 'e'},
    'Type': {0: 1, 1: 1, 2: 1, 3: 2, 4: 2},
    'Number of Beams': {0: 60, 1: 60, 2: 60, 3: 60, 4: 60},
    'Number of Columns': {0: 25, 1: 25, 2: 25, 3: 25, 4: 25},
    'Total Weight': {0: 120, 1: 125, 2: 130, 3: 145, 4: 145},
    'Warehouse1 Distance to Site Location': {0: 968, 1: 447, 2: 580, 3: 245, 4: 100},
    'Warehouse2 Distance to Site Location': {0: 220, 1: 513, 2: 123, 3: 35, 4: 940},
    'Warehouse3 Distance to Site Location': {0: 215, 1: 617, 2: 319, 3: 175, 4: 228},
    'Minimum Distance to Site Location': {0: 215, 1: 447, 2: 123, 3: 35, 4: 100},
    'Date of Registeration': {0: 0, 1: 0, 2: 0, 3: 0, 4: 0},
    'Earliest Time to Deliver': {0: 8, 1: 9, 2: 7, 3: 8, 4: 8},
    'Latest Time to Deliver': {0: 10, 1: 10, 2: 11, 3: 12, 4: 9},
    'Frame Cost': {0: 3720, 1: 3875, 2: 4030, 3: 4495, 4: 4495},
    'Transportation Cost': {0: 516, 1: 1117.5, 2: 319.8, 3: 101.5, 4: 290},
    'Date of Delivery': {0: 8, 1: 9, 2: 7, 3: 8, 4: 8}
})

初始化参数

import copy

current_day = 0
Charge = [250, 130, 140, 200]
Capacities = {
    1: {"Warehouse1":250, "Warehouse2":250, "Warehouse3":250}, 
    2: {"Warehouse1":130, "Warehouse2":130, "Warehouse3":130}, 
    3: {"Warehouse1":140, "Warehouse2":140, "Warehouse3":140},
    4: {"Warehouse1":200, "Warehouse2":200, "Warehouse3":200}
}
Daily_Capacities = []
Indicator = 0
Feasible_Distribution_Plan = pd.DataFrame()  # 补充初始化,避免运行报错

仓库选择函数

def Select_Warhouse(df, li):
    min_col = None
    min_val = float('inf')
    results = []

    for dict_item in li:
        for key in dict_item.keys():
            matching_col = [col for col in df.columns if key in col]
            if matching_col:
                col_name = matching_col[0]
                col_val = df.iloc[0][col_name]
                results.append((col_name, col_val))
                if col_val < min_val:
                    min_col = col_name
                    min_val = col_val
    output = [el for el in li if list(el.keys())[0] in min_col.split()[0]]
    return str(*output[0].keys())

主循环逻辑

while len(df) > 0:
    
    if current_day % 15 == 0 and current_day != 0 and Indicator == 0:
        for i, j in zip(Capacities, Charge):
            for key in Capacities[i]:
                Capacities[i][key] = Capacities[i][key] + j
    
    Indicator = 0
    
    select = df[df['Date of Delivery'] == current_day]
    if len(select) == 0:
        Daily_Capacities.append(copy.deepcopy(Capacities))        
        current_day += 1
        continue
    
    if len(select) > 1:
        Indicator = 1
        select = select[select['Total Weight'] == select['Total Weight'].max()]
    
    if len(select) > 1:
        select = select[select['Latest Time to Deliver'] == select['Latest Time to Deliver'].min()]
    
    if len(select) > 1:
        select = select.sample()
  
    Available_Warehouses = []
    for key, value in Capacities[select['Type'].iloc[0]].items():
        if select['Total Weight'].iloc[0] <= value:
                Available_Warehouses.append({key:value})
    
    if len(Available_Warehouses) == 0:
        df.loc[select.index, 'Date of Delivery'] += 1
        if Indicator == 1:
            continue        
        Daily_Capacities.append(copy.deepcopy(Capacities))
        current_day += 1
        continue
                
    elif len(Available_Warehouses) == 1:
        Warehouse = str(*Available_Warehouses[0].keys())
        
    elif len(Available_Warehouses) > 1:
        Warehouse = Select_Warhouse(select, Available_Warehouses)
                        
    Feasible_Distribution_Plan = Feasible_Distribution_Plan.append(select.iloc[0], ignore_index= True)
    # 异常代码行
    Feasible_Distribution_Plan['Distance to Site Location'] = Feasible_Distribution_Plan.iloc[-1]['{} Distance to Site Location'.format(Warehouse)]
    df.drop(select.index, inplace= True)
    Capacities[select['Type'].iloc[0]][Warehouse] -= select.iloc[0]['Total Weight']
    
    if Indicator == 1:
        continue
    
    Daily_Capacities.append(copy.deepcopy(Capacities))        
    current_day += 1             

Feasible_Distribution_Plan['Date of Delivery'] = Feasible_Distribution_Plan['Date of Delivery'].astype('int32')
        
Feasible_Distribution_Plan

异常代码行

Feasible_Distribution_Plan['Distance to Site Location'] = Feasible_Distribution_Plan.iloc[-1]['{} Distance to Site Location'.format(Warehouse)]

解决方案

你的问题出在赋值逻辑:每次追加行后,你直接把整个Distance to Site Location列设置成最后一行对应仓库的距离,导致所有行的该值都被覆盖成最新的那个。正确做法是只给刚追加的那一行赋值,而非整列。

方式1:追加前给行添加列(推荐)

先复制选中的行,添加新列后再追加到目标DataFrame:

# 替换原有的append和赋值两行
selected_row = select.iloc[0].copy()
selected_row['Distance to Site Location'] = selected_row[f"{Warehouse} Distance to Site Location"]
Feasible_Distribution_Plan = Feasible_Distribution_Plan.append(selected_row, ignore_index=True)

方式2:定位最后一行索引赋值

如果要保留先追加再赋值的逻辑,通过索引定位到刚添加的最后一行,仅修改该行的值:

# 追加行后执行
last_idx = Feasible_Distribution_Plan.index[-1]
Feasible_Distribution_Plan.loc[last_idx, 'Distance to Site Location'] = Feasible_Distribution_Plan.iloc[-1][f"{Warehouse} Distance to Site Location"]

额外优化建议

  1. 避免循环中频繁调用append:Pandas的DataFrame是不可变结构,每次append都会创建新对象,循环次数多了效率极低。建议先把所有要添加的行存入列表,最后一次性转成DataFrame:
# 初始化列表存行
plan_rows = []

# 循环中替换append逻辑
selected_row = select.iloc[0].copy()
selected_row['Distance to Site Location'] = selected_row[f"{Warehouse} Distance to Site Location"]
plan_rows.append(selected_row)

# 循环结束后生成DataFrame
Feasible_Distribution_Plan = pd.DataFrame(plan_rows)
  1. 原代码缺少Feasible_Distribution_Plan的初始化,运行会报错,必须先添加Feasible_Distribution_Plan = pd.DataFrame()。

内容的提问来源于stack exchange,提问作者Ahmad__fazli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 13:55:00