74 lines
2.1 KiB
Python
74 lines
2.1 KiB
Python
|
import pandas as pd
|
||
|
import numpy as np
|
||
|
|
||
|
score_method = "qty"
|
||
|
columns = [
|
||
|
"mpn",
|
||
|
"value",
|
||
|
"voltage_min",
|
||
|
"voltage_max",
|
||
|
"tolerance-",
|
||
|
"tolerance+",
|
||
|
]
|
||
|
parts = {
|
||
|
"C1": (None, 100e-9, 10, np.inf, None, None),
|
||
|
"C1a": (None, 100e-9, 10, 10, None, None),
|
||
|
"C2": (None, 100e-9, 16, np.inf, 0.20, 0.30),
|
||
|
"C2a": (None, 100e-9, 16, np.inf, None, None),
|
||
|
"C2b": (None, 100e-9, 12, np.inf, None, None),
|
||
|
"C3": (None, 100e-9, 0, np.inf, None, None),
|
||
|
"C4": (None, 10e-9, 10, np.inf, None, None),
|
||
|
"C5": (None, 10e-9, 12, np.inf, None, None),
|
||
|
}
|
||
|
|
||
|
nominal = pd.DataFrame(
|
||
|
[v for _, v in parts.items()],
|
||
|
index=parts.keys(),
|
||
|
columns=columns,
|
||
|
)
|
||
|
actual = nominal.copy(deep=True)
|
||
|
remaining = nominal.copy(deep=True)
|
||
|
|
||
|
# add temporary columns
|
||
|
remaining.insert(1, "matches", None, True)
|
||
|
remaining.insert(2, "score", -np.inf, True)
|
||
|
remaining.insert(3, "match_mpn", None, True)
|
||
|
|
||
|
# determine matches
|
||
|
for idx, row in remaining.iterrows():
|
||
|
matches = []
|
||
|
for ii, rr in remaining.iterrows():
|
||
|
if (ii == idx) or (
|
||
|
(rr["value"] == row["value"])
|
||
|
and (rr["voltage_min"] <= row["voltage_min"])
|
||
|
and (rr["voltage_max"] >= row["voltage_max"])
|
||
|
):
|
||
|
matches.append(ii)
|
||
|
remaining["matches"][idx] = matches
|
||
|
|
||
|
n = 0
|
||
|
while len(remaining.index) > 0:
|
||
|
for idx, row in remaining.iterrows():
|
||
|
if score_method == "qty":
|
||
|
# score by qty
|
||
|
remaining["score"][idx] = len(remaining["matches"][idx])
|
||
|
else:
|
||
|
# score by price reduction
|
||
|
pass
|
||
|
|
||
|
best_idx = remaining["score"].idxmax()
|
||
|
best_score = remaining["score"].max()
|
||
|
|
||
|
print(f"Step {n}: {best_idx} matched {len(remaining['matches'][best_idx]):d} parts (score: {best_score})")
|
||
|
|
||
|
for cmp in remaining["matches"][best_idx]:
|
||
|
if cmp in remaining.index:
|
||
|
actual.loc[cmp] = nominal.loc[best_idx]
|
||
|
|
||
|
# remove matched parts
|
||
|
remaining.drop(remaining["matches"][best_idx], inplace=True)
|
||
|
for idx in remaining.index:
|
||
|
remaining["matches"].loc[idx] = set(remaining["matches"][idx]).intersection(remaining.index)
|
||
|
|
||
|
n += 1
|