python - 带替换的 Python 条件枚举
问题描述
我有一个名为fleet_df的数据框,如下所示:
Vehicle_ID Capacity
001 5
002 6
003 10
我还有一个变量total_demand:
total_demand = 55
我想要的是枚举所有更换车辆的组合,只要 Total_Capacity 的总和大于或等于 total_volume 且小于或等于 total_volume 的两倍。
示例输出:
Scenario Vehicle_IDs Total_Capacity
1 001, 001, 001, 003, 003, 003, 003 55
2 003, 003, 003, 003, 003, 003, 003 70
...
我认为这样的事情会起作用,但到目前为止还没有运气:
enumerate(i for i in fleet_df['Capacity'].values.tolist() if (total_demand <= i) and (i <= total_demand * 2))
我错过了什么?
解决方案
我认为你也许可以做这样的事情 - 获取行索引的组合,为每个行组合找到容量总和并根据条件过滤它们
fleet_df = pd.DataFrame({'Vehicle_ID': ['001', '002', '003'],
'Capacity': [5, 6, 10]})
# Set the index as 'Vehicle_ID'
fleet_df.set_index(['Vehicle_ID'], inplace=True)
total_demand = 55
n = 10
final_df = pd.DataFrame([])
for i in range(1, n):
comb_indices = list(comb for comb in itertools.combinations_with_replacement(fleet_df.index, r=i))
comb_rows = pd.DataFrame([fleet_df.loc[comb, 'Capacity'].sum() for comb in comb_indices],
index=comb_indices, columns=['Total Capacity'])
final_df = final_df.append(comb_rows[(comb_rows['Total Capacity'] >= total_demand) & (comb_rows['Total Capacity'] <= 2*total_demand)])
final_df = final_df.rename_axis('Vehicle_IDs').reset_index().rename_axis('Scenarios')
print(final_df)
解释:
线
list(comb for comb in itertools.combinations_with_replacement(fleet_df.index, r=i))
将为您提供所有索引的组合,fleet_df
其中的i
元素来自0 to n
. 因此,与i=2
您将comb_indices
拥有
[('001', '001'), ('001', '002'), ('001', '003'), ('002', '002'), ('002', '003'), ('003', '003')]
comb_rows
接下来,使用与组合中的索引匹配的行创建一个临时数据框comb_indices
comb_rows = pd.DataFrame([fleet_df.loc[comb, 'Capacity'].sum() for comb in comb_indices], index=comb_indices, columns=['Total Capacity'])
最后,将总容量满足所需总需求的匹配行追加到final_df
comb_rows[(comb_rows['Total Capacity'] >= total_demand) & (comb_rows['Total Capacity'] <= 2*total_demand)]
一旦你有final_df
你想要的重命名索引。
这里的值n
是每个组合中元素的数量。当n
增加时,我不知道这将是一个有效的解决方案。并且n
取决于值total_demand
控制的重复可能有无限的可能性total_demand
。由于total_demand
价值增加的方式超过车辆的单个容量,价值也n
应该更高,以满足所有组合。的范围n
可以限定total_demand/max(capacity)
为(2*total demand)/min(capacity)
。我认为您应该在其中获得所有匹配的组合。所以,在这种情况下,你的范围n
将是
min_comb = int(total_demand/max(fleet_df['Capacity'].to_list()))
max_comb = int((2*total_demand)/min(fleet_df['Capacity'].to_list()))
for i in range(min_comb, max_comb+1):
...
...
最后结果:
Vehicle_IDs Total Capacity
Scenarios
0 (001, 003, 003, 003, 003, 003) 55
1 (002, 003, 003, 003, 003, 003) 56
2 (003, 003, 003, 003, 003, 003) 60
3 (001, 001, 001, 003, 003, 003, 003) 55
4 (001, 001, 002, 003, 003, 003, 003) 56
... ... ...
71 (002, 002, 002, 002, 003, 003, 003, 003, 003) 74
72 (002, 002, 002, 003, 003, 003, 003, 003, 003) 78
73 (002, 002, 003, 003, 003, 003, 003, 003, 003) 82
74 (002, 003, 003, 003, 003, 003, 003, 003, 003) 86
75 (003, 003, 003, 003, 003, 003, 003, 003, 003) 90
... ... ...
828 (001, 001, 001, 001, 001, 001, 001, 001, 001, ... 107
829 (001, 001, 001, 001, 001, 001, 001, 001, 001, ... 108
830 (001, 001, 001, 001, 001, 001, 001, 001, 001, ... 109
831 (001, 001, 001, 001, 001, 001, 001, 001, 001, ... 110
832 (001, 001, 001, 001, 001, 001, 001, 001, 001, ... 110
[833 rows x 2 columns]
对于更高的值可能有更好的解决方案,但这应该适用于样本数据集。
推荐阅读
- manim - 如何使用复杂函数变换任何图形(就像我们对线性变换所做的那样)?
- bash - 使用带有回声的 IFS
- node.js - 在没有JS框架的客户端渲染元素类名?(EJS)
- python - 名称 self 未定义
- javascript - Firefox中的角度日期管道解析错误“222-02-01”
- hibernate - 保存时未发生 Spring data jpa Constraint Violation 异常
- c# - 如何仅计算包含许多其他字符的非常长的字符串中的字母(Aa-Zz)?
- android-recyclerview - Recyclerview viewholder 项目点击渲染问题
- php - PDO 脚本中的 mySQL 语法问题
- python - 是否有查询以根据记录计数条件从 Sybase 表中检索数据