Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: sparse/compressed: work around bug in np.unique in earlier numpy versions #3393

Merged
merged 1 commit into from Feb 26, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions scipy/sparse/compressed.py
Expand Up @@ -15,7 +15,7 @@
from . import sparsetools
from .sputils import upcast, upcast_char, to_native, isdense, isshape, \
getdtype, isscalarlike, isintlike, IndexMixin, get_index_dtype, \
downcast_intp_index
downcast_intp_index, _safe_unique


class _cs_matrix(_data_matrix, _minmax_mixin, IndexMixin):
Expand Down Expand Up @@ -727,7 +727,7 @@ def _insert_many(self, i, j, x):
# Collate old and new in chunks by major index
indices_parts = []
data_parts = []
ui, ui_indptr = np.unique(i, return_index=True)
ui, ui_indptr = _safe_unique(i, return_index=True)
ui_indptr = np.append(ui_indptr, len(j))
new_nnzs = np.diff(ui_indptr)
prev = 0
Expand All @@ -739,7 +739,7 @@ def _insert_many(self, i, j, x):
data_parts.append(self.data[start:stop])

# handle duplicate j: keep last setting
uj, uj_indptr = np.unique(j[js:je][::-1], return_index=True)
uj, uj_indptr = _safe_unique(j[js:je][::-1], return_index=True)
if len(uj) == je - js:
indices_parts.append(j[js:je])
data_parts.append(x[js:je])
Expand Down
51 changes: 51 additions & 0 deletions scipy/sparse/sputils.py
Expand Up @@ -9,6 +9,8 @@
import warnings
import numpy as np

from scipy.lib._version import NumpyVersion

# keep this list syncronized with sparsetools
#supported_dtypes = ['bool', 'int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32',
# 'int64', 'uint64', 'float32', 'float64',
Expand Down Expand Up @@ -330,3 +332,52 @@ def _index_to_arrays(self, i, j):
raise IndexError("Index dimension must be <= 2")

return i, j


if NumpyVersion(np.__version__) > '1.7.0-dev':
_safe_unique = np.unique
else:
def _safe_unique(ar, return_index=False, return_inverse=False):
"""
Copy of numpy.unique() from Numpy 1.7.1.

Earlier versions have bugs in how return_index behaves.
"""
try:
ar = ar.flatten()
except AttributeError:
if not return_inverse and not return_index:
items = sorted(set(ar))
return np.asarray(items)
else:
ar = np.asanyarray(ar).flatten()

if ar.size == 0:
if return_inverse and return_index:
return ar, np.empty(0, np.bool), np.empty(0, np.bool)
elif return_inverse or return_index:
return ar, np.empty(0, np.bool)
else:
return ar

if return_inverse or return_index:
if return_index:
perm = ar.argsort(kind='mergesort')
else:
perm = ar.argsort()
aux = ar[perm]
flag = np.concatenate(([True], aux[1:] != aux[:-1]))
if return_inverse:
iflag = np.cumsum(flag) - 1
iperm = perm.argsort()
if return_index:
return aux[flag], perm[flag], iflag[iperm]
else:
return aux[flag], iflag[iperm]
else:
return aux[flag], perm[flag]

else:
ar.sort()
flag = np.concatenate(([True], ar[1:] != ar[:-1]))
return ar[flag]