<h3 dir="auto">Describe your issue.</h3>
<p dir="auto">It seems like there is a bug when we try to use <code class="notranslate">stats.zscore</code> with a masked array that has a masked <code class="notranslate">nan</code> value at index 0, and with <code class="notranslate">nan_policy='omit'</code>. In such cases, the function returns an array filled with <code class="notranslate">nan</code> values.</p>
<p dir="auto">It seems to be caused by the following line, which checks whether the array is constant:</p>
<p dir="auto"><a href="https://github.com/scipy/scipy/blob/dde50595862a4f9cede24b5d1c86935c30f1f88a/scipy/stats/_stats_py.py#L2877"><code class="notranslate">isconst = (_first(a, axis) == a).all(axis=axis, keepdims=True)</code></a></p>
<p dir="auto">In this specific case, <code class="notranslate">isconst</code> is evaluated to <code class="notranslate">True</code> (when in reality it should be evaluated to <code class="notranslate">False</code>), and the outputs are set to nan (when in reality they shouldn't)</p>
<h3 dir="auto">Reproducing Code Example</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from scipy.stats import zscore
import numpy as np

# With a masked array
A = np.array([np.nan, 1,2,3])
masked_A = np.ma.masked_array(A, np.isnan(A), copy=False, fill_value=np.nan)
z = zscore(masked_A, axis=0, nan_policy='omit').filled()
print(z)  # [nan nan nan nan] : z is filled with nan (this is a bug?)

# Without a masked array
z = zscore(A, axis=0, nan_policy='omit')
print(z)  # [nan -1.22474487 0 -1.22474487] nan values are omitted (as expected)"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">scipy</span>.<span class="pl-s1">stats</span> <span class="pl-k">import</span> <span class="pl-s1">zscore</span>
<span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>

<span class="pl-c"># With a masked array</span>
<span class="pl-v">A</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-s1">np</span>.<span class="pl-s1">nan</span>, <span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>])
<span class="pl-s1">masked_A</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-s1">ma</span>.<span class="pl-en">masked_array</span>(<span class="pl-v">A</span>, <span class="pl-s1">np</span>.<span class="pl-en">isnan</span>(<span class="pl-v">A</span>), <span class="pl-s1">copy</span><span class="pl-c1">=</span><span class="pl-c1">False</span>, <span class="pl-s1">fill_value</span><span class="pl-c1">=</span><span class="pl-s1">np</span>.<span class="pl-s1">nan</span>)
<span class="pl-s1">z</span> <span class="pl-c1">=</span> <span class="pl-en">zscore</span>(<span class="pl-s1">masked_A</span>, <span class="pl-s1">axis</span><span class="pl-c1">=</span><span class="pl-c1">0</span>, <span class="pl-s1">nan_policy</span><span class="pl-c1">=</span><span class="pl-s">'omit'</span>).<span class="pl-en">filled</span>()
<span class="pl-en">print</span>(<span class="pl-s1">z</span>)  <span class="pl-c"># [nan nan nan nan] : z is filled with nan (this is a bug?)</span>

<span class="pl-c"># Without a masked array</span>
<span class="pl-s1">z</span> <span class="pl-c1">=</span> <span class="pl-en">zscore</span>(<span class="pl-v">A</span>, <span class="pl-s1">axis</span><span class="pl-c1">=</span><span class="pl-c1">0</span>, <span class="pl-s1">nan_policy</span><span class="pl-c1">=</span><span class="pl-s">'omit'</span>)
<span class="pl-en">print</span>(<span class="pl-s1">z</span>)  <span class="pl-c"># [nan -1.22474487 0 -1.22474487] nan values are omitted (as expected)</span></pre></div>
<h3 dir="auto">Error message</h3>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="No error message"><pre class="notranslate">No error message</pre></div>
<h3 dir="auto">SciPy/NumPy/Python version information</h3>
<p dir="auto"><code class="notranslate">1.9.3 1.23.5 sys.version_info(major=3, minor=10, micro=8, releaselevel='final', serial=0)</code></p>
<p dir="auto"><em>Note from <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/mdhaber/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/mdhaber">@mdhaber</a>: This is a deep issue that is slated to be addressed as part of <a href="https://chanzuckerberg.com/eoss/proposals/scipy-fundamental-tools-for-biomedical-research/" rel="nofollow">this project</a>. Before composing a PR related to this issue, please comment below or - even better - consider resolving another <a href="https://github.com/scipy/scipy/issues">open issue</a>!</em></p>
<p dir="auto">This is the general case for <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="269763965" data-permission-text="Title is private" data-url="https://github.com/scipy/scipy/issues/8108" data-hovercard-type="pull_request" data-hovercard-url="/scipy/scipy/pull/8108/hovercard" href="https://github.com/scipy/scipy/pull/8108">#8108</a><br>
<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="269763965" data-permission-text="Title is private" data-url="https://github.com/scipy/scipy/issues/8108" data-hovercard-type="pull_request" data-hovercard-url="/scipy/scipy/pull/8108/hovercard?comment_id=377947155&amp;comment_type=issue_comment" href="https://github.com/scipy/scipy/pull/8108#issuecomment-377947155">#8108 (comment)</a></p>
<p dir="auto">currently there is no special handling of nans.</p>
<p dir="auto">AFAICS,  trimming functions trim1, trimboth treat nan as an extreme observation.</p>
<h3 dir="auto">Reproducing code example:</h3>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; stats.zscore([1,1,1,1,1.1, 5, np.nan])
array([ nan,  nan,  nan,  nan,  nan,  nan,  nan])

&gt;&gt;&gt; stats.sigmaclip([1,1,1,1,1.1, 5, np.nan])
&lt;several RuntimeWarning: invalid value encountered in ...&gt;
SigmaclipResult(clipped=array([], dtype=float64), lower=nan, upper=nan)

&gt;&gt;&gt; stats.trimboth([1,1,1,1,1.1, 5, -5, np.nan], 0.25)
array([ 1. ,  1. ,  1. ,  1.1])
"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt; stats.zscore([1,1,1,1,1.1, 5, np.nan])
array([ nan,  nan,  nan,  nan,  nan,  nan,  nan])

&gt;&gt;&gt; stats.sigmaclip([1,1,1,1,1.1, 5, np.nan])
&lt;several RuntimeWarning: invalid value encountered in ...&gt;
SigmaclipResult(clipped=array([], dtype=float64), lower=nan, upper=nan)

&gt;&gt;&gt; stats.trimboth([1,1,1,1,1.1, 5, -5, np.nan], 0.25)
array([ 1. ,  1. ,  1. ,  1.1])

</code></pre></div>