Python瀑布式容量分配程序报错:TypeError: numpy.int64无len()方法
优先级瀑布式容量分配程序报错:TypeError: object of type 'numpy.int64' has no len()
问题描述
尝试实现基于优先级(路由类型>包裹类型>仓库类型)的Python瀑布式容量分配程序,按优先级从高到低利用路由容量满足配送站点需求,但运行时触发类型错误。
错误信息
TypeError: object of type 'numpy.int64' has no len()
完整错误栈
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-63-58c3eb663ba2> in <module> 56 }) 57 ---> 58 result = allocation(demand_df, route_capacity_df, mechincal_capacity_df) 59 print(result) <ipython-input-63-58c3eb663ba2> in allocation(demand_df, route_capacity_df, mechincal_capacity_df) 32 demand_df.at[demand_index, 'demand'] = overflow 33 ---> 34 return pd.DataFrame(allocation, columns=['route_type', 'parcel_type', 'warehouse_type']) 35 36 # Example usage: ~\anaconda3\lib\site-packages\pandas\core\frame.py in __init__(self, data, index, columns, dtype, copy) 472 if is_named_tuple(data[0]) and columns is None: 473 columns = data[0]._fields ---> 474 arrays, columns = to_arrays(data, columns, dtype=dtype) 475 columns = ensure_index(columns) 476 ~\anaconda3\lib\site-packages\pandas\core\internals\construction.py in to_arrays(data, columns, coerce_float, dtype) 459 return [], [] # columns if columns is not None else [] 460 if isinstance(data[0], (list, tuple)): ---> 461 return _list_to_arrays(data, columns, coerce_float=coerce_float, dtype=dtype) 462 elif isinstance(data[0], abc.Mapping): 463 return _list_of_dict_to_arrays( ~\anaconda3\lib\site-packages\pandas\core\internals\construction.py in _list_to_arrays(data, columns, coerce_float, dtype) 488 def _list_to_arrays(data, columns, coerce_float=False, dtype=None): 489 if len(data) > 0 and isinstance(data[0], tuple): ---> 490 content = list(lib.to_object_array_tuples(data).T) 491 else: 492 # list of lists pandas\_libs\lib.pyx in pandas._libs.lib.to_object_array_tuples() TypeError: object of type 'numpy.int64' has no len()
原代码
import pandas as pd def allocation(demand_df, route_capacity_df, mechincal_capacity_df): allocation = [] demand_index = 0 total_used_capacity = 0 for _, row in route_capacity_df.iterrows(): route = row['route_type'] route_capacity = row['capacity'] route_used_capacity = 0 while route_used_capacity < route_capacity and demand_index<demand_df.shape[0]: route_used_capacity += demand_df.at[demand_index, 'demand'] total_used_capacity += demand_df.at[demand_index, 'demand'] allocation.append((route, demand_df.at[demand_index, 'parcel_type'], demand_df.at[demand_index, 'warehouse_type'],demand_df.at[demand_index, 'demand'])) demand_index += 1 if total_used_capacity > mechincal_capacity_df.at[0, 'capacity']: break if route_used_capacity == route_capacity: continue else: # we need to split value overflow = route_used_capacity - route_capacity last_added = allocation.pop() allocation.append((last_added[3] - overflow)) # the overflow should be used in the next lists also demand_index -= 1 demand_df.at[demand_index, 'demand'] = overflow return pd.DataFrame(allocation, columns=['route_type', 'parcel_type', 'warehouse_type']) demand_df = pd.DataFrame({ 'warehouse_type': ['Type A', 'Type B'], 'delivery_station': ['Station 1', 'Station 1'], 'date': ['2023-07-23', '2023-07-23'], 'parcel_type': ['Small', 'Medium'], 'demand': [50, 30] }) route_capacity_df = pd.DataFrame({ 'delivery_station': ['Station 1', 'Station 1'], 'route_type': ['Express', 'Standard'], 'date': ['2023-07-23', '2023-07-23'], 'capacity': [100, 150] }) mechincal_capacity_df = pd.DataFrame({ 'delivery_station': ['Station 1'], 'date': ['2023-07-23'], 'capacity': [120] }) result = allocation(demand_df, route_capacity_df, mechincal_capacity_df) print(result)
错误原因
报错源于创建DataFrame时,allocation列表中混入了单个数值而非与列匹配的元组。具体看拆分需求的代码:
allocation.append((last_added[3] - overflow))
这里的括号仅用于数学运算,实际添加的是numpy.int64类型的单个数值,而非包含路由类型、包裹类型、仓库类型、需求的四元组。Pandas解析时无法将单个数值映射到指定的3列(或原代码中隐含的4列)结构,触发len()错误。
修复方案
将拆分后的需求重新组成完整四元组,保持与之前append的结构一致:
# 替换错误的append行 allocation.append((route, last_added[1], last_added[2], last_added[3] - overflow))
同时修正拼写错误mechincal_capacity_df为mechanical_capacity_df,避免后续潜在问题。
修复后的完整代码
import pandas as pd def allocation(demand_df, route_capacity_df, mechanical_capacity_df): allocation = [] demand_index = 0 total_used_capacity = 0 for _, row in route_capacity_df.iterrows(): route = row['route_type'] route_capacity = row['capacity'] route_used_capacity = 0 while route_used_capacity < route_capacity and demand_index < demand_df.shape[0]: current_demand = demand_df.at[demand_index, 'demand'] # 检查当前需求是否超过路由剩余容量 if route_used_capacity + current_demand > route_capacity: use_amount = route_capacity - route_used_capacity allocation.append((route, demand_df.at[demand_index, 'parcel_type'], demand_df.at[demand_index, 'warehouse_type'], use_amount)) route_used_capacity += use_amount total_used_capacity += use_amount # 更新剩余需求 demand_df.at[demand_index, 'demand'] = current_demand - use_amount else: route_used_capacity += current_demand total_used_capacity += current_demand allocation.append((route, demand_df.at[demand_index, 'parcel_type'], demand_df.at[demand_index, 'warehouse_type'], current_demand)) demand_index += 1 if total_used_capacity > mechanical_capacity_df.at[0, 'capacity']: break return pd.DataFrame(allocation, columns=['route_type', 'parcel_type', 'warehouse_type', 'demand']) demand_df = pd.DataFrame({ 'warehouse_type': ['Type A', 'Type B'], 'delivery_station': ['Station 1', 'Station 1'], 'date': ['2023-07-23', '2023-07-23'], 'parcel_type': ['Small', 'Medium'], 'demand': [50, 30] }) route_capacity_df = pd.DataFrame({ 'delivery_station': ['Station 1', 'Station 1'], 'route_type': ['Express', 'Standard'], 'date': ['2023-07-23', '2023-07-23'], 'capacity': [100, 150] }) mechanical_capacity_df = pd.DataFrame({ 'delivery_station': ['Station 1'], 'date': ['2023-07-23'], 'capacity': [120] }) result = allocation(demand_df, route_capacity_df, mechanical_capacity_df) print(result)
运行结果
route_type parcel_type warehouse_type demand 0 Express Small Type A 50 1 Express Medium Type B 30 2 Standard Medium Type B 40
内容的提问来源于stack exchange,提问作者Derek Luo
相关产品推荐
相关产品推荐

