Can't use inequality on a Pandas Series containing variables

99 views
Skip to first unread message

Michel Jadoul

unread,
Oct 8, 2018, 5:02:01 PM10/8/18
to pyomo...@googlegroups.com
Hello,

I expected to receive a Pandas Series of _InequalityExpression in return for the expression below.
Instead, this expression returns an exception  (see log below):
(stocks.decisions.decision <= 1000)

Here are the types involved:
type(stocks.decisions)                  ==> pandas.core.frame.DataFrame
type
(stocks.decisions.decision)         ==> pandas.core.series.Series
type
(stocks.decisions.decision.loc[1])  ==> pyomo.core.base.var._GeneralVarData


In contrast, the following expression makes no problem and returns a Series of _SumExpression :
stocks.decisions.decision + 1000

It looks like the inequality expression is cast on a boolean, when I hoped to get just a _InequalityExpression .
Is there a specific reason that the ad-hoc overload does work for "+" (__add__) operator and not for the "<=" (__le__) operator ?
Or would that be a Pyomo issue?
Or a Pandas issue?
Would there be some nice workaround? 
I will need a lot of similar expressions, involving joins over several Pandas Dataframes.

Thanks for you suggestions,

Michel

log of this exception

TypeError: Attempting to form a compound inequality with two lower bounds

The inequality expression:
    stocks.decisions[0]  <=  1000.0
contains non-constant terms (variables) that were evaluated in an
unexpected Boolean context at
  File 'C:\Users\mjtoys\Anaconda3\lib\site-packages\pandas\core\ops.py', line 763:
    result = lib.scalar_compare(x, y, op)

Evaluating Pyomo variables in a Boolean context, e.g.
    if expression <= 5:
is generally invalid.  If you want to obtain the Boolean value of the
expression based on the current variable values, explicitly evaluate the
expression using the value() function:
    if value(expression) <= 5:
or
    if value(expression <= 5):
 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-27-a0255d0d7ceb> in <module>()
----> 1 (stocks.decisions.decision <= 1000)

~\Anaconda3\lib\site-packages\pandas\core\ops.py in wrapper(self, other, axis)
    877 
    878             with np.errstate(all='ignore'):
--> 879                 res = na_op(values, other)
    880             if is_scalar(res):
    881                 raise TypeError('Could not compare {typ} type with Series'

~\Anaconda3\lib\site-packages\pandas\core\ops.py in na_op(x, y)
    781 
    782         if is_object_dtype(x.dtype):
--> 783             result = _comp_method_OBJECT_ARRAY(op, x, y)
    784         else:
    785 

~\Anaconda3\lib\site-packages\pandas\core\ops.py in _comp_method_OBJECT_ARRAY(op, x, y)
    761         result = lib.vec_compare(x, y, op)
    762     else:
--> 763         result = lib.scalar_compare(x, y, op)
    764     return result
    765 

pandas/_libs/lib.pyx in pandas._libs.lib.scalar_compare()

~\Anaconda3\lib\site-packages\pyomo\core\kernel\numvalue.py in __le__(self, other)
    441         (Called in response to 'self <= other' or 'other >= self'.)
    442         """
--> 443         return generate_relational_expression(_le, self, other)
    444 
    445     def __ge__(self,other):

~\Anaconda3\lib\site-packages\pyomo\core\kernel\expr_coopr3.py in generate_relational_expression(etype, lhs, rhs)
   1486                 raise TypeError(chainedInequalityErrorMessage(
   1487                     "Attempting to form a compound inequality with two "
-> 1488                     "%s bounds" % ('lower' if match[0][0] else 'upper',)))
   1489             if not match[0][1]:
   1490                 cloned_from = prevExpr._cloned_from + (cloned_from[1],)

TypeError: Attempting to form a compound inequality with two lower bounds

The inequality expression:
    stocks.decisions[0]  <=  1000.0
contains non-constant terms (variables) that were evaluated in an
unexpected Boolean context at
  File 'C:\Users\mjtoys\Anaconda3\lib\site-packages\pandas\core\ops.py', line 763:
    result = lib.scalar_compare(x, y, op)

Evaluating Pyomo variables in a Boolean context, e.g.
    if expression <= 5:
is generally invalid.  If you want to obtain the Boolean value of the
expression based on the current variable values, explicitly evaluate the
expression using the value() function:
    if value(expression) <= 5:
or
    if value(expression <= 5):

Michel Jadoul

unread,
Oct 10, 2018, 2:40:00 PM10/10/18
to Pyomo Forum
I asked the same question on the pandas-dev github:


It is suggested that an interface is needed to get the desired result.

Then I have this question:
Did I take the wrong way?
I liked the idea to use pandas for building my models, maybe that's a bad idea?

Thanks for your comments.

Michel
Reply all
Reply to author
Forward
0 new messages