def adjust_context_window( op: ops.WindowOp, timecontext: TimeContext, scope: Optional['Scope'] = None ) -> TimeContext: # adjust time context by preceding and following begin, end = timecontext preceding = op.window.preceding if preceding is not None: if isinstance(preceding, ir.IntervalScalar): from ibis.backends.pandas.execution import execute preceding = execute(preceding) if preceding and not isinstance(preceding, (int, np.integer)): begin = begin - preceding following = op.window.following if following is not None: if isinstance(following, ir.IntervalScalar): from ibis.backends.pandas.execution import execute following = execute(following) if following and not isinstance(following, (int, np.integer)): end = end + following return (begin, end)
def test_lag(t, df, row_offset, default, row_window): expr = t.dup_strings.lag(row_offset, default=default).over(row_window) result = expr.execute() expected = df.dup_strings.shift(execute(row_offset)) if default is not ibis.NA: expected = expected.fillna(execute(default)) tm.assert_series_equal(result, expected)
def test_lag_delta(t, df, range_offset, default, range_window): expr = t.dup_strings.lag(range_offset, default=default).over(range_window) result = expr.execute() expected = (df[['plain_datetimes_naive', 'dup_strings' ]].set_index('plain_datetimes_naive').squeeze().shift( freq=execute(range_offset)).reindex( df.plain_datetimes_naive).reset_index(drop=True)) if default is not ibis.NA: expected = expected.fillna(execute(default)) tm.assert_series_equal(result, expected)
def test_struct_field_literal(value): struct = ibis.literal(value) assert struct.type() == dt.Struct.from_tuples([("fruit", dt.string), ("weight", dt.int8)]) expr = struct['fruit'] result = execute(expr) assert result == "pear" expr = struct['weight'] result = execute(expr) assert result == 0
def test_ifelse_returning_bool(): one = ibis.literal(1) two = ibis.literal(2) true = ibis.literal(True) false = ibis.literal(False) expr = ibis.ifelse(one + one == two, true, false) result = execute(expr) assert result is True
def adjust_context_custom_asof_join( op: ops.AsOfJoin, timecontext: TimeContext, scope: Optional[Scope] = None, ) -> TimeContext: """Shifts both the begin and end in the same direction.""" begin, end = timecontext timedelta = execute(op.tolerance) return (begin - timedelta, end - timedelta)
def adjust_context_asof_join(op: ops.AsOfJoin, scope: 'Scope', timecontext: TimeContext) -> TimeContext: begin, end = timecontext if op.tolerance is not None: from ibis.backends.pandas.execution import execute timedelta = execute(op.tolerance) return (begin - timedelta, end) return timecontext
def test_is_computable_input(): class MyObject: def __init__(self, value: float) -> None: self.value = value def __getattr__(self, name: str) -> Any: return getattr(self.value, name) def __hash__(self) -> int: return hash((type(self), self.value)) def __eq__(self, other): return ( isinstance(other, type(self)) and isinstance(self, type(other)) and self.value == other.value ) def __float__(self) -> float: return self.value @execute_node.register(ops.Add, int, MyObject) def add_int_my_object(op, left, right, **kwargs): return left + right.value # This multimethod must be implemented to play nicely with other value # types like columns and literals. In other words, for a custom # non-expression object to play nicely it must somehow map to one of the # types in ibis/expr/datatypes.py @dt.infer.register(MyObject) def infer_my_object(_, **kwargs): return dt.float64 @is_computable_input.register(MyObject) def is_computable_input_my_object(_): return True one = ibis.literal(1) two = MyObject(2.0) assert is_computable_input(two) three = one + two four = three + 1 result = execute(four) assert result == 4.0 del execute_node[ops.Add, int, MyObject] execute_node.reorder() execute_node._cache.clear() del dt.infer.funcs[(MyObject,)] dt.infer.reorder() dt.infer._cache.clear()
def test_timestamp_functions(case_func, expected_func): v = L('2015-09-01 14:48:05.359').cast('timestamp') vt = datetime.datetime( year=2015, month=9, day=1, hour=14, minute=48, second=5, microsecond=359000, ) result = case_func(v) expected = expected_func(vt) assert execute(result) == expected
def test_signature_does_not_match_input_type(dtype, value): @udf.elementwise([dtype], dtype) def func(x): return x df = pd.DataFrame({"col": [value]}) table = ibis.pandas.from_dataframe(df) result = execute(table.col) assert isinstance(result, pd.Series) result = result.tolist() assert result == [value] assert type(result[0]) is type(value)
def test_execute_with_same_hash_value_in_scope(left, right, expected_value, expected_type, left_dtype, right_dtype): @udf.elementwise([left_dtype, right_dtype], left_dtype) def my_func(x, y): return x df = pd.DataFrame({"left": [left], "right": [right]}) table = ibis.pandas.from_dataframe(df) expr = my_func(table.left, table.right) result = execute(expr) assert isinstance(result, pd.Series) result = result.tolist() assert result == [expected_value] assert type(result[0]) is expected_type
def test_pre_execute_basic(): """ Test that pre_execute has intercepted execution and provided its own scope dict """ @pre_execute.register(ops.Add) def pre_execute_test(op, *clients, scope=None, **kwargs): return Scope({op: 4}, None) one = ibis.literal(1) expr = one + one result = execute(expr) assert result == 4 del pre_execute.funcs[(ops.Add,)] pre_execute.reorder() pre_execute._cache.clear()
def test_nullif(t, df, left, right, expected, compare): expr = left(t).nullif(right(t)) result = execute(expr) compare(result, expected(df))
def test_cast_timestamp_scalar_naive(to, expected): literal_expr = ibis.literal(pd.Timestamp('now')) value = literal_expr.cast(to) result = execute(value) raw = execute(literal_expr) assert result == expected(raw)
def test_cast_timestamp_scalar(to, expected, tz): literal_expr = ibis.literal(pd.Timestamp('now').tz_localize(tz)) value = literal_expr.cast(to) result = execute(value) raw = execute(literal_expr) assert result == expected(raw)
def test_missing_data_sources(): t = ibis.table([('a', 'string')]) expr = t.a.length() with pytest.raises(com.UnboundExpressionError): execute(expr)
def test_execute_parameter_only(): param = ibis.param('int64') result = execute(param, params={param: 42}) assert result == 42