Skip to content

Commit

Permalink
Merge remote-tracking branch 'ibis-project/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
xmnlab committed Apr 25, 2018
2 parents 31e69e6 + 93cc4ba commit 90a41f1
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 56 deletions.
2 changes: 1 addition & 1 deletion ci/requirements-docs-3.6.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ dependencies:
- python-hdfs>=2.0.16
- regex
- six
- sphinx_rtd_theme
- sphinx_rtd_theme<0.3
- sqlalchemy>=1.0.0,<1.1.15
- toolz
- xorg-libxpm
Expand Down
7 changes: 0 additions & 7 deletions docs/README

This file was deleted.

4 changes: 0 additions & 4 deletions docs/requirements-docs.txt

This file was deleted.

5 changes: 4 additions & 1 deletion ibis/expr/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2366,7 +2366,10 @@ def _interval_property(target_unit):
rmul=_interval_rmul,

__floordiv__=_interval_floordiv,
floordiv=_interval_floordiv
floordiv=_interval_floordiv,

__neg__=negate,
negate=negate,
)

_add_methods(ir.IntervalValue, _interval_value_methods)
Expand Down
64 changes: 41 additions & 23 deletions ibis/expr/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ class TypeOf(UnaryOp):


class Negate(UnaryOp):
arg = Arg(rlz.numeric)
arg = Arg(rlz.one_of((rlz.numeric(), rlz.interval())))
output_type = rlz.typeof('arg')


Expand Down Expand Up @@ -733,9 +733,18 @@ class StringConcat(ValueOp):

class ParseURL(ValueOp):
arg = Arg(rlz.string)
extract = Arg(rlz.isin(['PROTOCOL', 'HOST', 'PATH',
'REF', 'AUTHORITY', 'FILE',
'USERINFO', 'QUERY']))
extract = Arg(
rlz.isin({
'PROTOCOL',
'HOST',
'PATH',
'REF',
'AUTHORITY',
'FILE',
'USERINFO',
'QUERY'
})
)
key = Arg(rlz.string, default=None)
output_type = rlz.shape_like('arg', dt.string)

Expand Down Expand Up @@ -2462,7 +2471,7 @@ class Date(UnaryOp):

class TimestampFromUNIX(ValueOp):
arg = Arg(rlz.any)
unit = Arg(rlz.isin(['s', 'ms', 'us']))
unit = Arg(rlz.isin({'s', 'ms', 'us'}))
output_type = rlz.shape_like('arg', dt.timestamp)


Expand Down Expand Up @@ -2540,38 +2549,47 @@ class TimestampDiff(BinaryOp):
output_type = rlz.shape_like('left', dt.Interval('s'))


class IntervalAdd(BinaryOp):
left = Arg(rlz.interval)
right = Arg(rlz.interval)

class IntervalBinaryOp(BinaryOp):
def output_type(self):
args = [arg.cast(arg.type().value_type) for arg in self.args]
expr = rlz.numeric_like(args, operator.add)(self)
dtype = dt.Interval(self.left.type().unit, expr.type())
args = [
arg.cast(arg.type().value_type)
if isinstance(arg.type(), dt.Interval)
else arg for arg in self.args
]
expr = rlz.numeric_like(args, self.__class__.op)(self)
left_dtype = self.left.type()
dtype_type = type(left_dtype)
additional_args = {
attr: getattr(left_dtype, attr) for attr in dtype_type.__slots__
if attr not in {'unit', 'value_type'}
}
dtype = dtype_type(left_dtype.unit, expr.type(), **additional_args)
return rlz.shape_like(self.args, dtype=dtype)


class IntervalMultiply(BinaryOp):
class IntervalAdd(IntervalBinaryOp):
left = Arg(rlz.interval)
right = Arg(rlz.numeric)
right = Arg(rlz.interval)
op = operator.add

def output_type(self):
args = [self.left.cast(self.left.type().value_type), self.right]
expr = rlz.numeric_like(args, operator.mul)(self)
dtype = dt.Interval(self.left.type().unit, expr.type())
return rlz.shape_like(self.args, dtype=dtype)

class IntervalMultiply(IntervalBinaryOp):
left = Arg(rlz.interval)
right = Arg(rlz.numeric)
op = operator.mul


class IntervalFloorDivide(BinaryOp):
class IntervalFloorDivide(IntervalBinaryOp):
left = Arg(rlz.interval)
right = Arg(rlz.numeric)
output_type = rlz.shape_like('left')
op = operator.floordiv


class IntervalFromInteger(ValueOp):
arg = Arg(rlz.integer)
unit = Arg(rlz.isin(['Y', 'Q', 'M', 'W', 'D',
'h', 'm', 's', 'ms', 'us', 'ns']))
unit = Arg(rlz.isin({
'Y', 'Q', 'M', 'W', 'D', 'h', 'm', 's', 'ms', 'us', 'ns'
}))

@property
def resolution(self):
Expand Down
4 changes: 0 additions & 4 deletions ibis/expr/signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,6 @@ def from_dtypes(cls, dtypes):
for i, dtype in enumerate(dtypes))

def validate(self, *args, **kwargs):
if len(args) > len(self.keys()):
raise TypeError('takes {!d} positional arguments but {!d} were '
'given'.format(len(self.keys()), len(args)))

result = []
for i, (name, argument) in enumerate(self.items()):
if i < len(args):
Expand Down
16 changes: 16 additions & 0 deletions ibis/expr/tests/test_value_exprs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1286,3 +1286,19 @@ def test_nullable_column_propagated():

s = t.b + t.f
assert s.type().nullable is False


@pytest.mark.parametrize(
'base_expr',
[
ibis.table([('interval_col', dt.Interval(unit='D'))]).interval_col,
ibis.second(42),
]
)
def test_interval_negate(base_expr):
expr = -base_expr
expr2 = base_expr.negate()
expr3 = ibis.negate(base_expr)
assert isinstance(expr.op(), ops.Negate)
assert expr.equals(expr2)
assert expr.equals(expr3)
24 changes: 8 additions & 16 deletions ibis/pandas/execution/temporal.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,15 @@ def execute_timestamp_add_datetime_series(op, left, right, **kwargs):

@execute_node.register(ops.IntervalAdd, datetime.timedelta, datetime.timedelta)
def execute_interval_add_delta_delta(op, left, right, **kwargs):
return pd.Timedelta(left) + pd.Timedelta(right)
return op.op(pd.Timedelta(left), pd.Timedelta(right))


@execute_node.register(ops.IntervalAdd, datetime.timedelta, pd.Series)
def execute_interval_add_delta_series(op, left, right, **kwargs):
return pd.Timedelta(left) + right
@execute_node.register(
ops.IntervalMultiply, datetime.timedelta, numeric_types + (pd.Series,)
)
def execute_interval_add_multiply_delta_series(op, left, right, **kwargs):
return op.op(pd.Timedelta(left), right)


@execute_node.register(
Expand Down Expand Up @@ -144,24 +147,13 @@ def execute_timestamp_diff_series_datetime(op, left, right, **kwargs):
@execute_node.register(
ops.IntervalMultiply, pd.Series, numeric_types + (pd.Series,)
)
def execute_interval_multiply_series_numeric(op, left, right, **kwargs):
return left * right


@execute_node.register(
ops.IntervalMultiply, datetime.timedelta, numeric_types + (pd.Series,)
)
def execute_interval_multiply_delta_numeric(op, left, right, **kwargs):
return pd.Timedelta(left) * right


@execute_node.register(
ops.IntervalFloorDivide,
(pd.Timedelta, pd.Series),
numeric_types + (pd.Series,)
)
def execute_interval_floor_divide(op, left, right, **kwargs):
return left // right
def execute_interval_multiply_fdiv_series_numeric(op, left, right, **kwargs):
return op.op(left, right)


@execute_node.register(ops.TimestampFromUNIX, (pd.Series,) + integer_types)
Expand Down

0 comments on commit 90a41f1

Please sign in to comment.