pulp icon indicating copy to clipboard operation
pulp copied to clipboard

LpVariable dict fails when pandas series are used (`if first` issue)

Open andrea-taverna opened this issue 2 years ago • 1 comments

System:

  • python 3.10.6 on Linux x86_64
  • PuLP 2.7
  • pandas 1.5.3

Code:

S = [1,2,3]
T = pd.Series([1,2,3])
U = pd.Series([1,2,3])

print("creating x")
x = LpVariable.dict("x", (S,T),"B") # works :)
print(x)

print("creating y")
y = LpVariable.dict("y", (U,T),"B") # does not work :(
print(y)

Expected output:

creating x
{(1, 1): x_1_1, (1, 2): x_1_2, (1, 3): x_1_3, (2, 1): x_2_1, (2, 2): x_2_2, (2, 3): x_2_3, (3, 1): x_3_1, (3, 2): x_3_2, (3, 3): x_3_3}
creating y
{(1, 1): y_1_1, (1, 2): y_1_2, (1, 3): y_1_3, (2, 1): y_2_1, (2, 2): y_2_2, (2, 3): y_2_3, (3, 1): y_3_1, (3, 2): y_3_2, (3, 3): y_3_3}

Actual output:

ValueError                                Traceback (most recent call last)
Cell In[11], line 10
      7 print(x)
      9 print("creating y")
---> 10 y = LpVariable.dict("y", (U,T),"B") # does not :(
     11 print(y)

File ***/venv/lib/python3.10/site-packages/pulp/pulp.py:444, in LpVariable.dict(cls, name, indices, lowBound, upBound, cat)
    442 nres = []
    443 if res:
--> 444     if first:
    445         for f in first:
    446             nres.extend([[f] + r for r in res])

File ***/venv/lib/python3.10/site-packages/pandas/core/generic.py:1527, in NDFrame.__nonzero__(self)
   1525 @final
   1526 def __nonzero__(self) -> NoReturn:
-> 1527     raise ValueError(
   1528         f"The truth value of a {type(self).__name__} is ambiguous. "
   1529         "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
   1530     )

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Description: when creating y the code on pulp.py line 444 has a check if first: ... where first is the first element of the indexes tuples ((S,T) for x and (U,T) for y). With the current system it seems the if instruction does something different to series (in the example U) than just checking if they're None, hence it fails. IIRC, in other versions/configurations it did work fine in both cases.

Indeed the following check raises the same exception:

if U:
    print("Hey")

while this works:

if U is not None:
    print("Hey")

andrea-taverna avatar Feb 25 '23 21:02 andrea-taverna

Thanks for the report. I don't think this code has changed recently. Maybe changing the line to:

if first is not None:

could work. Would you like to make a PR? It would be nice to have a test case, but we do not test pandas because we do not required it for pulp. Which is also a reason why we do not support pandas that well.

I guess we could add pandas in the dev requirements for testing though...

pchtsp avatar Jan 19 '24 09:01 pchtsp