Skip to content
This repository was archived by the owner on Feb 2, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import sdc.datatypes.series.init

import sdc.extensions.indexes.range_index_ext
import sdc.extensions.indexes.int64_index_ext

from ._version import get_versions

Expand Down
67 changes: 39 additions & 28 deletions sdc/datatypes/common_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,17 @@
from sdc.functions import numpy_like
from sdc.str_arr_type import string_array_type, StringArrayType
from sdc.datatypes.range_index_type import RangeIndexType
from sdc.datatypes.int64_index_type import Int64IndexType
from sdc.str_arr_ext import (num_total_chars, append_string_array_to,
str_arr_is_na, pre_alloc_string_array, str_arr_set_na, string_array_type,
cp_str_list_to_array, create_str_arr_from_list, get_utf8_size,
str_arr_set_na_by_mask)
from sdc.utilities.prange_utils import parallel_chunks
from sdc.utilities.utils import sdc_overload, sdc_register_jitable
from sdc.utilities.sdc_typing_utils import (find_common_dtype_from_numpy_dtypes,
TypeChecker)
from sdc.utilities.sdc_typing_utils import (
find_common_dtype_from_numpy_dtypes,
TypeChecker)
from sdc.utilities.sdc_typing_utils import sdc_pandas_index_types


class SDCLimitation(Exception):
Expand All @@ -71,18 +74,20 @@ def hpat_arrays_append(A, B):
def hpat_arrays_append_overload(A, B):
"""Function for appending underlying arrays (A and B) or list/tuple of arrays B to an array A"""

A_is_range_index = isinstance(A, RangeIndexType)
B_is_range_index = isinstance(B, RangeIndexType)
if isinstance(A, (types.Array, RangeIndexType)):
if isinstance(B, (types.Array, RangeIndexType)):
use_A_array = isinstance(A, (RangeIndexType, Int64IndexType))
use_B_array = isinstance(B, (RangeIndexType, Int64IndexType))
if isinstance(A, (types.Array, RangeIndexType, Int64IndexType)):
if isinstance(B, (types.Array, RangeIndexType, Int64IndexType)):
def _append_single_numeric_impl(A, B):
_A = A.values if A_is_range_index == True else A # noqa
_B = B.values if B_is_range_index == True else B # noqa
_A = A.values if use_A_array == True else A # noqa
_B = B.values if use_B_array == True else B # noqa
return numpy.concatenate((_A, _B,))

return _append_single_numeric_impl
elif isinstance(B, (types.UniTuple, types.List)) and isinstance(B.dtype, (types.Array, RangeIndexType)):
B_dtype_is_range_index = isinstance(B.dtype, RangeIndexType)

elif (isinstance(B, (types.UniTuple, types.List))
and isinstance(B.dtype, (types.Array, RangeIndexType, Int64IndexType))):
B_dtype_is_index = isinstance(B.dtype, (RangeIndexType, Int64IndexType))
numba_common_dtype = find_common_dtype_from_numpy_dtypes([A.dtype, B.dtype.dtype], [])

# TODO: refactor to use numpy.concatenate when Numba supports building a tuple at runtime
Expand All @@ -92,10 +97,10 @@ def _append_list_numeric_impl(A, B):
new_data = numpy.empty(total_length, numba_common_dtype)

stop = len(A)
_A = numpy.array(A) if A_is_range_index == True else A # noqa
_A = numpy.array(A) if use_A_array == True else A # noqa
new_data[:stop] = _A
for arr in B:
_arr = numpy.array(arr) if B_dtype_is_range_index == True else arr # noqa
_arr = arr.values if B_dtype_is_index == True else arr # noqa
start = stop
stop = start + len(_arr)
new_data[start:stop] = _arr
Expand Down Expand Up @@ -218,12 +223,13 @@ def sdc_join_series_indexes_overload(left, right):
"""Function for joining arrays left and right in a way similar to pandas.join 'outer' algorithm"""

# check that both operands are of types used for representing Pandas indexes
if not (isinstance(left, (types.Array, StringArrayType, RangeIndexType))
and isinstance(right, (types.Array, StringArrayType, RangeIndexType))):
if not (isinstance(left, sdc_pandas_index_types) and isinstance(right, sdc_pandas_index_types)
and not isinstance(left, types.NoneType)
and not isinstance(right, types.NoneType)):
return None

convert_left = isinstance(left, RangeIndexType)
convert_right = isinstance(right, RangeIndexType)
convert_left = isinstance(left, (RangeIndexType, Int64IndexType))
convert_right = isinstance(right, (RangeIndexType, Int64IndexType))

def _convert_to_arrays_impl(left, right):
_left = left.values if convert_left == True else left # noqa
Expand All @@ -243,10 +249,9 @@ def sdc_join_range_indexes_impl(left, right):

return sdc_join_range_indexes_impl

elif isinstance(left, RangeIndexType) and isinstance(right, types.Array):
return _convert_to_arrays_impl

elif isinstance(left, types.Array) and isinstance(right, RangeIndexType):
elif (isinstance(left, (RangeIndexType, Int64IndexType, types.Array))
and isinstance(right, (RangeIndexType, Int64IndexType, types.Array))
and not (isinstance(left, types.Array) and isinstance(right, types.Array))):
return _convert_to_arrays_impl

# TODO: remove code duplication below and merge numeric and StringArray impls into one
Expand Down Expand Up @@ -618,13 +623,16 @@ def _sdc_take(data, indexes):
@sdc_overload(_sdc_take)
def _sdc_take_overload(data, indexes):

if not isinstance(data, (types.Array, StringArrayType, RangeIndexType)):
valid_data_types = (types.Array,) + sdc_pandas_index_types
if not (isinstance(data, valid_data_types) and not isinstance(data, types.NoneType)):
return None
if not (isinstance(indexes, (types.Array, types.List))

if not (isinstance(indexes, (types.Array, types.List, Int64IndexType))
and isinstance(indexes.dtype, (types.Integer, types.ListType))):
return None

if isinstance(indexes.dtype, types.ListType) and isinstance(data, (types.Array, types.List, RangeIndexType)):
if (isinstance(indexes.dtype, types.ListType)
and isinstance(data, (types.Array, types.List, RangeIndexType, Int64IndexType))):
arr_dtype = data.dtype

def _sdc_take_list_impl(data, indexes):
Expand Down Expand Up @@ -677,7 +685,7 @@ def _sdc_take_list_str_impl(data, indexes):

return _sdc_take_list_str_impl

elif isinstance(data, (types.Array, RangeIndexType)):
elif isinstance(data, (types.Array, RangeIndexType, Int64IndexType)):
arr_dtype = data.dtype

def _sdc_take_array_impl(data, indexes):
Expand Down Expand Up @@ -740,6 +748,7 @@ def sdc_reindex_series_overload(arr, index, name, by_index):
""" Reindexes series data by new index following the logic of pandas.core.indexing.check_bool_indexer """

range_indexes = isinstance(index, RangeIndexType) and isinstance(by_index, RangeIndexType)
int64_indexes = isinstance(index, Int64IndexType) and isinstance(by_index, Int64IndexType)
data_dtype, index_dtype = arr.dtype, index.dtype
data_is_str_arr = isinstance(arr.dtype, types.UnicodeType)

Expand All @@ -748,6 +757,8 @@ def sdc_reindex_series_impl(arr, index, name, by_index):
# no reindexing is needed if indexes are equal
if range_indexes == True: # noqa
equal_indexes = numpy_like.array_equal(index, by_index)
elif int64_indexes == True: # noqa
equal_indexes = numpy_like.array_equal(index, by_index)
else:
equal_indexes = False
if (index is by_index or equal_indexes):
Expand All @@ -772,10 +783,10 @@ def sdc_reindex_series_impl(arr, index, name, by_index):
map_index_to_position[value] = i

index_mismatch = 0
# FIXME: TypingError in parfor step (wrong promotion to float64?) if prange is used
for i in numpy.arange(len(by_index)):
if by_index[i] in map_index_to_position:
pos_in_self = map_index_to_position[by_index[i]]
for i in numba.prange(len(by_index)):
val = by_index[i]
if val in map_index_to_position:
pos_in_self = map_index_to_position[val]
_res_data[i] = arr[pos_in_self]
if data_is_str_arr == True: # noqa
res_data_nan_mask[i] = isna(arr, i)
Expand Down
3 changes: 2 additions & 1 deletion sdc/datatypes/hpat_pandas_dataframe_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
gen_impl_generator, find_common_dtype_from_numpy_dtypes)
from sdc.str_arr_ext import StringArrayType
from sdc.datatypes.range_index_type import RangeIndexType
from sdc.datatypes.int64_index_type import Int64IndexType

from sdc.hiframes.pd_dataframe_type import DataFrameType
from sdc.hiframes.pd_dataframe_ext import init_dataframe_internal, get_structure_maps
Expand Down Expand Up @@ -2257,7 +2258,7 @@ def sdc_pandas_dataframe_accessor_getitem(self, idx):

if accessor == 'at':
num_idx = (isinstance(idx[0], types.Number)
and isinstance(self.dataframe.index, (types.Array, types.NoneType, RangeIndexType)))
and isinstance(self.dataframe.index, (types.NoneType, RangeIndexType, Int64IndexType)))
str_idx = (isinstance(idx[0], (types.UnicodeType, types.StringLiteral))
and isinstance(self.dataframe.index, StringArrayType))
if isinstance(idx, types.Tuple) and isinstance(idx[1], types.StringLiteral):
Expand Down
6 changes: 4 additions & 2 deletions sdc/datatypes/hpat_pandas_series_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
find_common_dtype_from_numpy_dtypes, has_literal_value,
has_python_value)
from sdc.datatypes.range_index_type import RangeIndexType
from sdc.datatypes.int64_index_type import Int64IndexType
from sdc.datatypes.common_functions import (sdc_join_series_indexes, sdc_arrays_argsort, sdc_reindex_series)
from sdc.datatypes.hpat_pandas_rolling_types import (
gen_sdc_pandas_rolling_overload_body, sdc_pandas_rolling_docstring_tmpl)
Expand Down Expand Up @@ -618,7 +619,7 @@ def sdc_pandas_series_setitem(self, idx, value):
def sdc_pandas_series_setitem_no_reindexing_impl(self, idx, value):

if assign_via_idx_mask == True: # noqa
# FIXME_Numba#5157: using asarray since eq impl for RangeIndexType returns list
# FIXME_Numba#5157: using asarray since eq impl for index types returns list
_idx = numpy.asarray(self._index == idx)
elif assign_via_idx_data == True: # noqa
_idx = idx._data
Expand Down Expand Up @@ -4034,7 +4035,8 @@ def hpat_pandas_series_dropna(self, axis=0, inplace=False):
ty_checker.raise_exc(inplace, 'bool', 'inplace')

if (isinstance(self.data.dtype, types.Number)
and isinstance(self.index, (types.Number, types.NoneType, RangeIndexType))):
and (isinstance(self.index, types.NoneType)
or isinstance(self.index.dtype, types.Number))):
def hpat_pandas_series_dropna_impl(self, axis=0, inplace=False):
index = self.index
return numpy_like.dropna(self._data, index, self._name)
Expand Down
65 changes: 65 additions & 0 deletions sdc/datatypes/int64_index_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
# *****************************************************************************
# Copyright (c) 2020, Intel Corporation All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# *****************************************************************************

from numba import types
from numba.extending import (
models,
register_model,
make_attribute_wrapper
)


class Int64IndexType(types.IterableType):
dtype = types.int64

def __init__(self, data, is_named=False):
self.data = data
self.is_named = is_named
super(Int64IndexType, self).__init__(
name='Int64IndexType({}, {})'.format(data, is_named))

@property
def iterator_type(self):
res = self.data.iterator_type
return res


@register_model(Int64IndexType)
class Int64IndexModel(models.StructModel):
def __init__(self, dmm, fe_type):

data_type = fe_type.data
name_type = types.unicode_type if fe_type.is_named else types.none
members = [
('data', data_type),
('name', name_type),
]
models.StructModel.__init__(self, dmm, fe_type, members)


make_attribute_wrapper(Int64IndexType, 'data', '_data')
make_attribute_wrapper(Int64IndexType, 'name', '_name')
40 changes: 40 additions & 0 deletions sdc/extensions/indexes/indexes_generic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
# *****************************************************************************
# Copyright (c) 2019-2020, Intel Corporation All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# *****************************************************************************

import numba
import numpy as np
import pandas as pd

from numba import types


def _check_dtype_param_type(dtype):
""" Returns True is dtype is a valid type for dtype parameter and False otherwise.
Used in RangeIndex ctor and other methods that take dtype parameter. """

valid_dtype_types = (types.NoneType, types.Omitted, types.UnicodeType, types.NumberClass)
return isinstance(dtype, valid_dtype_types) or dtype is None
Loading