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

Disallow auto-densification. #220

Merged
merged 2 commits into from
Dec 13, 2018
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/generated/sparse.SparseArray.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ SparseArray
:toctree:

SparseArray.asformat
SparseArray.todense

6 changes: 6 additions & 0 deletions docs/generated/sparse.SparseArray.todense.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SparseArray.todense
===================

.. currentmodule:: sparse

.. automethod:: SparseArray.todense
2 changes: 1 addition & 1 deletion sparse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import os

_AUTO_DENSIFICATION_ENABLED = bool(int(os.environ.get('SPARSE_AUTO_DENSIFY', '1')))
_AUTO_DENSIFICATION_ENABLED = bool(int(os.environ.get('SPARSE_AUTO_DENSIFY', '0')))
_AUTO_WARN_ON_TOO_DENSE = bool(int(os.environ.get('SPARSE_WARN_ON_TOO_DENSE', '0')))

del os
2 changes: 1 addition & 1 deletion sparse/coo/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ def nanmean(x, axis=None, keepdims=False, dtype=None, out=None):
den = reduce(operator.mul, (x.shape[i] for i in axis), 1)
den -= nancount

if np.any(den == 0):
if (den == 0).any():
warnings.warn("Mean of empty slice", RuntimeWarning, stacklevel=2)

num = np.sum(x2, axis=axis, dtype=dtype, keepdims=keepdims)
Expand Down
8 changes: 0 additions & 8 deletions sparse/coo/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1449,14 +1449,6 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):

return result

def __array__(self, **kwargs):
from .. import _AUTO_DENSIFICATION_ENABLED as densify
if not densify:
raise RuntimeError('Cannot convert a sparse array to dense automatically. '
'To manually densify, use the todense method.')

return np.asarray(self.todense(), **kwargs)

def linear_loc(self):
"""
The nonzero coordinates of a flattened version of this array. Note that
Expand Down
37 changes: 37 additions & 0 deletions sparse/sparse_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from functools import reduce
import operator

import numpy as np

from .utils import _zero_of_dtype
from .compatibility import int

Expand Down Expand Up @@ -177,3 +179,38 @@ def asformat(self, format):
NotImplementedError
If the format isn't supported.
"""

@abstractmethod
def todense(self):
"""
Convert this :obj:`SparseArray` array to a dense :obj:`numpy.ndarray`. Note that
this may take a large amount of memory and time.

Returns
-------
numpy.ndarray
The converted dense array.

See Also
--------
DOK.todense : Equivalent :obj:`DOK` array method.
COO.todense : Equivalent :obj:`COO` array method.
scipy.sparse.coo_matrix.todense : Equivalent Scipy method.

Examples
--------
>>> import sparse
>>> x = np.random.randint(100, size=(7, 3))
>>> s = sparse.COO.from_numpy(x)
>>> x2 = s.todense()
>>> np.array_equal(x, x2)
True
"""

def __array__(self, **kwargs):
from . import _AUTO_DENSIFICATION_ENABLED as densify
if not densify:
raise RuntimeError('Cannot convert a sparse array to dense automatically. '
'To manually densify, use the todense method.')

return np.asarray(self.todense(), **kwargs)
16 changes: 9 additions & 7 deletions sparse/tests/test_coo.py
Original file line number Diff line number Diff line change
Expand Up @@ -1645,9 +1645,9 @@ def test_size():

def test_np_array():
s = sparse.random((20, 30, 40))
x = np.array(s)
assert isinstance(x, np.ndarray)
assert_eq(x, s)

with pytest.raises(RuntimeError):
np.array(s)


@pytest.mark.parametrize('shapes', [
Expand Down Expand Up @@ -2059,12 +2059,14 @@ def test_failed_densification():
import os
from importlib import reload

os.environ['SPARSE_AUTO_DENSIFY'] = '0'
os.environ['SPARSE_AUTO_DENSIFY'] = '1'
reload(sparse)

with pytest.raises(RuntimeError):
s = sparse.random((3, 4, 5), density=0.5)
np.array(s)
s = sparse.random((3, 4, 5), density=0.5)
x = np.array(s)

assert isinstance(x, np.ndarray)
assert_eq(s, x)

del os.environ['SPARSE_AUTO_DENSIFY']
reload(sparse)
Expand Down