Skip to content

Commit

Permalink
BUG: sparse/compressed: work around bug in np.unique in earlier numpy…
Browse files Browse the repository at this point in the history
… versions
  • Loading branch information
pv committed Feb 25, 2014
1 parent 46e840b commit e522b97
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
6 changes: 3 additions & 3 deletions scipy/sparse/compressed.py
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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]

0 comments on commit e522b97

Please sign in to comment.