<p dir="auto">While debugging <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="449969264" data-permission-text="Title is private" data-url="https://github.com/biocore/biom-format/issues/816" data-hovercard-type="issue" data-hovercard-url="/biocore/biom-format/issues/816/hovercard" href="https://github.com/biocore/biom-format/issues/816">biocore/biom-format#816</a>, we noticed that the return type of <code class="notranslate">__getitem__</code> for a sparse matrix object changed between SciPy versions.</p>
<p dir="auto">We did not see anything that stood out in the changelog regarding this, but we apologize if we overlooked something. We also attempted to identify what commit may have been associated with this but have so far not been successful. We would be happy to assist on or contribute a PR if one is appropriate here.</p>
<h4 dir="auto">Reproducing code example:</h4>
<p dir="auto">For SciPy 1.2.0:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; import scipy.sparse as sp
&gt;&gt;&gt; import sys, scipy, numpy; print(scipy.__version__, numpy.__version__, sys.version_info)
1.2.0 1.15.4 sys.version_info(major=3, minor=6, micro=5, releaselevel='final', serial=0)
&gt;&gt;&gt; print(type(sp.csr_matrix([[0, 1.0, 2], [3, 4, 5]])[0, 0]))
&lt;class 'numpy.float64'&gt;"><pre class="notranslate"><span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-k">import</span> <span class="pl-s1">scipy</span>.<span class="pl-s1">sparse</span> <span class="pl-k">as</span> <span class="pl-s1">sp</span>
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-k">import</span> <span class="pl-s1">sys</span>, <span class="pl-s1">scipy</span>, <span class="pl-s1">numpy</span>; <span class="pl-en">print</span>(<span class="pl-s1">scipy</span>.<span class="pl-s1">__version__</span>, <span class="pl-s1">numpy</span>.<span class="pl-s1">__version__</span>, <span class="pl-s1">sys</span>.<span class="pl-s1">version_info</span>)
<span class="pl-c1">1.2</span>.<span class="pl-c1">0</span> <span class="pl-c1">1.15</span>.<span class="pl-c1">4</span> <span class="pl-s1">sys</span>.<span class="pl-en">version_info</span>(<span class="pl-s1">major</span><span class="pl-c1">=</span><span class="pl-c1">3</span>, <span class="pl-s1">minor</span><span class="pl-c1">=</span><span class="pl-c1">6</span>, <span class="pl-s1">micro</span><span class="pl-c1">=</span><span class="pl-c1">5</span>, <span class="pl-s1">releaselevel</span><span class="pl-c1">=</span><span class="pl-s">'final'</span>, <span class="pl-s1">serial</span><span class="pl-c1">=</span><span class="pl-c1">0</span>)
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-en">print</span>(<span class="pl-en">type</span>(<span class="pl-s1">sp</span>.<span class="pl-en">csr_matrix</span>([[<span class="pl-c1">0</span>, <span class="pl-c1">1.0</span>, <span class="pl-c1">2</span>], [<span class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span class="pl-c1">5</span>]])[<span class="pl-c1">0</span>, <span class="pl-c1">0</span>]))
<span class="pl-c1">&lt;</span><span class="pl-k">class</span> <span class="pl-s">'numpy.float64'</span><span class="pl-c1">&gt;</span></pre></div>
<p dir="auto">For SciPy 1.3.0:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; import scipy.sparse as sp
&gt;&gt;&gt; import sys, scipy, numpy; print(scipy.__version__, numpy.__version__, sys.version_info)
1.3.0 1.16.3 sys.version_info(major=3, minor=7, micro=3, releaselevel='final', serial=0)
&gt;&gt;&gt; print(type(sp.csr_matrix([[0, 1.0, 2], [3, 4, 5]])[0, 0]))
&lt;class 'numpy.ndarray'&gt;"><pre class="notranslate"><span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-k">import</span> <span class="pl-s1">scipy</span>.<span class="pl-s1">sparse</span> <span class="pl-k">as</span> <span class="pl-s1">sp</span>
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-k">import</span> <span class="pl-s1">sys</span>, <span class="pl-s1">scipy</span>, <span class="pl-s1">numpy</span>; <span class="pl-en">print</span>(<span class="pl-s1">scipy</span>.<span class="pl-s1">__version__</span>, <span class="pl-s1">numpy</span>.<span class="pl-s1">__version__</span>, <span class="pl-s1">sys</span>.<span class="pl-s1">version_info</span>)
<span class="pl-c1">1.3</span>.<span class="pl-c1">0</span> <span class="pl-c1">1.16</span>.<span class="pl-c1">3</span> <span class="pl-s1">sys</span>.<span class="pl-en">version_info</span>(<span class="pl-s1">major</span><span class="pl-c1">=</span><span class="pl-c1">3</span>, <span class="pl-s1">minor</span><span class="pl-c1">=</span><span class="pl-c1">7</span>, <span class="pl-s1">micro</span><span class="pl-c1">=</span><span class="pl-c1">3</span>, <span class="pl-s1">releaselevel</span><span class="pl-c1">=</span><span class="pl-s">'final'</span>, <span class="pl-s1">serial</span><span class="pl-c1">=</span><span class="pl-c1">0</span>)
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-en">print</span>(<span class="pl-en">type</span>(<span class="pl-s1">sp</span>.<span class="pl-en">csr_matrix</span>([[<span class="pl-c1">0</span>, <span class="pl-c1">1.0</span>, <span class="pl-c1">2</span>], [<span class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span class="pl-c1">5</span>]])[<span class="pl-c1">0</span>, <span class="pl-c1">0</span>]))
<span class="pl-c1">&lt;</span><span class="pl-k">class</span> <span class="pl-s">'numpy.ndarray'</span><span class="pl-c1">&gt;</span></pre></div>
<p dir="auto">Behavior as observed with a 2D <code class="notranslate">np.array</code>:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; print(type(np.array([[0, 1.0, 2], [3, 4, 5]])[0, 0]))
&lt;class 'numpy.float64'&gt;"><pre class="notranslate"><span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-en">print</span>(<span class="pl-en">type</span>(<span class="pl-s1">np</span>.<span class="pl-en">array</span>([[<span class="pl-c1">0</span>, <span class="pl-c1">1.0</span>, <span class="pl-c1">2</span>], [<span class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span class="pl-c1">5</span>]])[<span class="pl-c1">0</span>, <span class="pl-c1">0</span>]))
<span class="pl-c1">&lt;</span><span class="pl-k">class</span> <span class="pl-s">'numpy.float64'</span><span class="pl-c1">&gt;</span></pre></div>
<p dir="auto">Indexing csr or csc sparce matrix return an array of one element with scipy 1.3, With previous version it returned a scalar. I believe it is an oversight since lil_matrix indexing still return a scalar.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import scipy
import numpy as np
print(type(scipy.sparse.csr_matrix(np.eye(3))[0,0]))
print(type(scipy.sparse.csc_matrix(np.eye(3))[0,0]))
print(type(scipy.sparse.lil_matrix(np.eye(3))[0,0]))"><pre class="notranslate"><code class="notranslate">import scipy
import numpy as np
print(type(scipy.sparse.csr_matrix(np.eye(3))[0,0]))
print(type(scipy.sparse.csc_matrix(np.eye(3))[0,0]))
print(type(scipy.sparse.lil_matrix(np.eye(3))[0,0]))
</code></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&lt;class 'numpy.ndarray'&gt;
&lt;class 'numpy.ndarray'&gt;
&lt;class 'numpy.float64'&gt;"><pre class="notranslate"><code class="notranslate">&lt;class 'numpy.ndarray'&gt;
&lt;class 'numpy.ndarray'&gt;
&lt;class 'numpy.float64'&gt;
</code></pre></div>
<h3 dir="auto">Scipy/Numpy/Python version information:</h3>
<p dir="auto">scipy 1.3.0<br>
numpy 1.16.3<br>
python 3.7.0</p>