<p dir="auto">Support for weights in <code class="notranslate">percentile</code> would be nice to have.  A quick look suggests <a href="https://github.com/nudomarinero/wquantiles">https://github.com/nudomarinero/wquantiles</a>; I'd be happy to make a PR out of this implementation if there's interest.</p>
<p dir="auto">For our work we frequently need to compute weighted quantiles.  This is especially important when we need to weigh data from recent years more heavily in making predictions.</p>
<p dir="auto">I've put together a function (called <code class="notranslate">weighted_quantile</code>) largely based on the source code of <code class="notranslate">np.percentile</code>.  It allows one to input weights along a single dimension, as a dict <code class="notranslate">w_dict</code>.  Below are some manual tests, using <code class="notranslate">xarray</code> as starting point:</p>
<p dir="auto">When all weights = 1, it's identical to using <code class="notranslate">np.percentile</code>:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; ar0
&lt;xarray.DataArray (x: 3, y: 4)&gt;
array([[3, 4, 8, 1],
       [5, 3, 7, 9],
       [4, 9, 6, 2]])
Coordinates:
  * x        (x) |S1 'a' 'b' 'c'
  * y        (y) int64 0 1 2 3
&gt;&gt;&gt; np.percentile(ar0, q=[25, 50, 75], axis=-1)
array([[ 2.5 ,  4.5 ,  3.5 ],
       [ 3.5 ,  6.  ,  5.  ],
       [ 5.  ,  7.5 ,  6.75]])
&gt;&gt;&gt; weighted_quantile(da=ar0, q=[0.25, 0.5, 0.75], dim='y', w_dict={'y': [1,1,1,1]})
&lt;xarray.DataArray (quantile: 3, x: 3)&gt;
array([[ 2.5 ,  4.5 ,  3.5 ],
       [ 3.5 ,  6.  ,  5.  ],
       [ 5.  ,  7.5 ,  6.75]])
Coordinates:
  * x         (x) |S1 'a' 'b' 'c'
  * quantile  (quantile) float64 0.25 0.5 0.75"><pre class="notranslate"><span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">ar0</span>
<span class="pl-c1">&lt;</span><span class="pl-s1">xarray</span>.<span class="pl-v">DataArray</span> (<span class="pl-s1">x</span>: <span class="pl-c1">3</span>, <span class="pl-s1">y</span>: <span class="pl-c1">4</span>)<span class="pl-c1">&gt;</span>
<span class="pl-en">array</span>([[<span class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span class="pl-c1">8</span>, <span class="pl-c1">1</span>],
       [<span class="pl-c1">5</span>, <span class="pl-c1">3</span>, <span class="pl-c1">7</span>, <span class="pl-c1">9</span>],
       [<span class="pl-c1">4</span>, <span class="pl-c1">9</span>, <span class="pl-c1">6</span>, <span class="pl-c1">2</span>]])
<span class="pl-v">Coordinates</span>:
  <span class="pl-c1">*</span> <span class="pl-en">x</span>        (<span class="pl-s1">x</span>) <span class="pl-c1">|</span><span class="pl-v">S1</span> <span class="pl-s">'a'</span> <span class="pl-s">'b'</span> <span class="pl-s">'c'</span>
  <span class="pl-c1">*</span> <span class="pl-en">y</span>        (<span class="pl-s1">y</span>) <span class="pl-s1">int64</span> <span class="pl-c1">0</span> <span class="pl-c1">1</span> <span class="pl-c1">2</span> <span class="pl-c1">3</span>
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">np</span>.<span class="pl-en">percentile</span>(<span class="pl-s1">ar0</span>, <span class="pl-s1">q</span><span class="pl-c1">=</span>[<span class="pl-c1">25</span>, <span class="pl-c1">50</span>, <span class="pl-c1">75</span>], <span class="pl-s1">axis</span><span class="pl-c1">=</span><span class="pl-c1">-</span><span class="pl-c1">1</span>)
<span class="pl-en">array</span>([[ <span class="pl-c1">2.5</span> ,  <span class="pl-c1">4.5</span> ,  <span class="pl-c1">3.5</span> ],
       [ <span class="pl-c1">3.5</span> ,  <span class="pl-c1">6.</span>  ,  <span class="pl-c1">5.</span>  ],
       [ <span class="pl-c1">5.</span>  ,  <span class="pl-c1">7.5</span> ,  <span class="pl-c1">6.75</span>]])
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-en">weighted_quantile</span>(<span class="pl-s1">da</span><span class="pl-c1">=</span><span class="pl-s1">ar0</span>, <span class="pl-s1">q</span><span class="pl-c1">=</span>[<span class="pl-c1">0.25</span>, <span class="pl-c1">0.5</span>, <span class="pl-c1">0.75</span>], <span class="pl-s1">dim</span><span class="pl-c1">=</span><span class="pl-s">'y'</span>, <span class="pl-s1">w_dict</span><span class="pl-c1">=</span>{<span class="pl-s">'y'</span>: [<span class="pl-c1">1</span>,<span class="pl-c1">1</span>,<span class="pl-c1">1</span>,<span class="pl-c1">1</span>]})
<span class="pl-c1">&lt;</span><span class="pl-s1">xarray</span>.<span class="pl-v">DataArray</span> (<span class="pl-s1">quantile</span>: <span class="pl-c1">3</span>, <span class="pl-s1">x</span>: <span class="pl-c1">3</span>)<span class="pl-c1">&gt;</span>
<span class="pl-en">array</span>([[ <span class="pl-c1">2.5</span> ,  <span class="pl-c1">4.5</span> ,  <span class="pl-c1">3.5</span> ],
       [ <span class="pl-c1">3.5</span> ,  <span class="pl-c1">6.</span>  ,  <span class="pl-c1">5.</span>  ],
       [ <span class="pl-c1">5.</span>  ,  <span class="pl-c1">7.5</span> ,  <span class="pl-c1">6.75</span>]])
<span class="pl-v">Coordinates</span>:
  <span class="pl-c1">*</span> <span class="pl-en">x</span>         (<span class="pl-s1">x</span>) <span class="pl-c1">|</span><span class="pl-v">S1</span> <span class="pl-s">'a'</span> <span class="pl-s">'b'</span> <span class="pl-s">'c'</span>
  <span class="pl-c1">*</span> <span class="pl-en">quantile</span>  (<span class="pl-s1">quantile</span>) <span class="pl-s1">float64</span> <span class="pl-c1">0.25</span> <span class="pl-c1">0.5</span> <span class="pl-c1">0.75</span></pre></div>
<p dir="auto">Now different weights:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; weighted_quantile(da=ar0, q=[0.25, 0.5, 0.75], dim='y', w_dict={'y': [1,2,3,4.0]})
&lt;xarray.DataArray (quantile: 3, x: 3)&gt;
array([[ 3.25    ,  5.666667,  4.333333],
       [ 4.      ,  7.      ,  5.333333],
       [ 6.      ,  8.      ,  6.75    ]])
Coordinates:
  * x         (x) |S1 'a' 'b' 'c'
  * quantile  (quantile) float64 0.25 0.5 0.75"><pre class="notranslate"><span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-en">weighted_quantile</span>(<span class="pl-s1">da</span><span class="pl-c1">=</span><span class="pl-s1">ar0</span>, <span class="pl-s1">q</span><span class="pl-c1">=</span>[<span class="pl-c1">0.25</span>, <span class="pl-c1">0.5</span>, <span class="pl-c1">0.75</span>], <span class="pl-s1">dim</span><span class="pl-c1">=</span><span class="pl-s">'y'</span>, <span class="pl-s1">w_dict</span><span class="pl-c1">=</span>{<span class="pl-s">'y'</span>: [<span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>,<span class="pl-c1">4.0</span>]})
<span class="pl-c1">&lt;</span><span class="pl-s1">xarray</span>.<span class="pl-v">DataArray</span> (<span class="pl-s1">quantile</span>: <span class="pl-c1">3</span>, <span class="pl-s1">x</span>: <span class="pl-c1">3</span>)<span class="pl-c1">&gt;</span>
<span class="pl-en">array</span>([[ <span class="pl-c1">3.25</span>    ,  <span class="pl-c1">5.666667</span>,  <span class="pl-c1">4.333333</span>],
       [ <span class="pl-c1">4.</span>      ,  <span class="pl-c1">7.</span>      ,  <span class="pl-c1">5.333333</span>],
       [ <span class="pl-c1">6.</span>      ,  <span class="pl-c1">8.</span>      ,  <span class="pl-c1">6.75</span>    ]])
<span class="pl-v">Coordinates</span>:
  <span class="pl-c1">*</span> <span class="pl-en">x</span>         (<span class="pl-s1">x</span>) <span class="pl-c1">|</span><span class="pl-v">S1</span> <span class="pl-s">'a'</span> <span class="pl-s">'b'</span> <span class="pl-s">'c'</span>
  <span class="pl-c1">*</span> <span class="pl-en">quantile</span>  (<span class="pl-s1">quantile</span>) <span class="pl-s1">float64</span> <span class="pl-c1">0.25</span> <span class="pl-c1">0.5</span> <span class="pl-c1">0.75</span></pre></div>
<p dir="auto">Also handles nan values like <code class="notranslate">np.nanpercentile</code>:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; ar
&lt;xarray.DataArray (x: 2, y: 2, z: 2)&gt;
array([[[ nan,   3.],
        [ nan,   5.]],

       [[  8.,   1.],
        [ nan,   0.]]])
Coordinates:
  * x        (x) |S1 'a' 'b'
  * y        (y) int64 0 1
  * z        (z) int64 8 9
&gt;&gt;&gt; da_stacked = ar.stack(mi=['x', 'y'])
&gt;&gt;&gt; out = weighted_quantile(da=ar, q=[0.25, 0.5, 0.75], dim=['x', 'y'], w_dict={'x': [1, 1]})
&gt;&gt;&gt; out
&lt;xarray.DataArray (quantile: 3, z: 2)&gt;
array([[ 8.  ,  0.75],
       [ 8.  ,  2.  ],
       [ 8.  ,  3.5 ]])
Coordinates:
  * z         (z) int64 8 9
  * quantile  (quantile) float64 0.25 0.5 0.75
&gt;&gt;&gt;  np.nanpercentile(da_stacked, q=[25, 50, 75], axis=-1)
array([[ 8.  ,  0.75],
       [ 8.  ,  2.  ],
       [ 8.  ,  3.5 ]])"><pre class="notranslate"><span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">ar</span>
<span class="pl-c1">&lt;</span><span class="pl-s1">xarray</span>.<span class="pl-v">DataArray</span> (<span class="pl-s1">x</span>: <span class="pl-c1">2</span>, <span class="pl-s1">y</span>: <span class="pl-c1">2</span>, <span class="pl-s1">z</span>: <span class="pl-c1">2</span>)<span class="pl-c1">&gt;</span>
<span class="pl-en">array</span>([[[ <span class="pl-s1">nan</span>,   <span class="pl-c1">3.</span>],
        [ <span class="pl-s1">nan</span>,   <span class="pl-c1">5.</span>]],

       [[  <span class="pl-c1">8.</span>,   <span class="pl-c1">1.</span>],
        [ <span class="pl-s1">nan</span>,   <span class="pl-c1">0.</span>]]])
<span class="pl-v">Coordinates</span>:
  <span class="pl-c1">*</span> <span class="pl-en">x</span>        (<span class="pl-s1">x</span>) <span class="pl-c1">|</span><span class="pl-v">S1</span> <span class="pl-s">'a'</span> <span class="pl-s">'b'</span>
  <span class="pl-c1">*</span> <span class="pl-en">y</span>        (<span class="pl-s1">y</span>) <span class="pl-s1">int64</span> <span class="pl-c1">0</span> <span class="pl-c1">1</span>
  <span class="pl-c1">*</span> <span class="pl-en">z</span>        (<span class="pl-s1">z</span>) <span class="pl-s1">int64</span> <span class="pl-c1">8</span> <span class="pl-c1">9</span>
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">da_stacked</span> <span class="pl-c1">=</span> <span class="pl-s1">ar</span>.<span class="pl-en">stack</span>(<span class="pl-s1">mi</span><span class="pl-c1">=</span>[<span class="pl-s">'x'</span>, <span class="pl-s">'y'</span>])
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">out</span> <span class="pl-c1">=</span> <span class="pl-en">weighted_quantile</span>(<span class="pl-s1">da</span><span class="pl-c1">=</span><span class="pl-s1">ar</span>, <span class="pl-s1">q</span><span class="pl-c1">=</span>[<span class="pl-c1">0.25</span>, <span class="pl-c1">0.5</span>, <span class="pl-c1">0.75</span>], <span class="pl-s1">dim</span><span class="pl-c1">=</span>[<span class="pl-s">'x'</span>, <span class="pl-s">'y'</span>], <span class="pl-s1">w_dict</span><span class="pl-c1">=</span>{<span class="pl-s">'x'</span>: [<span class="pl-c1">1</span>, <span class="pl-c1">1</span>]})
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">out</span>
<span class="pl-c1">&lt;</span><span class="pl-s1">xarray</span>.<span class="pl-v">DataArray</span> (<span class="pl-s1">quantile</span>: <span class="pl-c1">3</span>, <span class="pl-s1">z</span>: <span class="pl-c1">2</span>)<span class="pl-c1">&gt;</span>
<span class="pl-en">array</span>([[ <span class="pl-c1">8.</span>  ,  <span class="pl-c1">0.75</span>],
       [ <span class="pl-c1">8.</span>  ,  <span class="pl-c1">2.</span>  ],
       [ <span class="pl-c1">8.</span>  ,  <span class="pl-c1">3.5</span> ]])
<span class="pl-v">Coordinates</span>:
  <span class="pl-c1">*</span> <span class="pl-en">z</span>         (<span class="pl-s1">z</span>) <span class="pl-s1">int64</span> <span class="pl-c1">8</span> <span class="pl-c1">9</span>
  <span class="pl-c1">*</span> <span class="pl-en">quantile</span>  (<span class="pl-s1">quantile</span>) <span class="pl-s1">float64</span> <span class="pl-c1">0.25</span> <span class="pl-c1">0.5</span> <span class="pl-c1">0.75</span>
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span>  <span class="pl-s1">np</span>.<span class="pl-en">nanpercentile</span>(<span class="pl-s1">da_stacked</span>, <span class="pl-s1">q</span><span class="pl-c1">=</span>[<span class="pl-c1">25</span>, <span class="pl-c1">50</span>, <span class="pl-c1">75</span>], <span class="pl-s1">axis</span><span class="pl-c1">=</span><span class="pl-c1">-</span><span class="pl-c1">1</span>)
<span class="pl-en">array</span>([[ <span class="pl-c1">8.</span>  ,  <span class="pl-c1">0.75</span>],
       [ <span class="pl-c1">8.</span>  ,  <span class="pl-c1">2.</span>  ],
       [ <span class="pl-c1">8.</span>  ,  <span class="pl-c1">3.5</span> ]])</pre></div>
<p dir="auto">Lastly, different interpolation schemes are consistent:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; out = weighted_quantile(da=ar, q=[0.25, 0.5, 0.75], dim=['x', 'y'], w_dict={'x': [1, 1]}, interpolation='nearest')
&gt;&gt;&gt; out
&lt;xarray.DataArray (quantile: 3, z: 2)&gt;
array([[ 8.,  1.],
       [ 8.,  3.],
       [ 8.,  3.]])
Coordinates:
  * z         (z) int64 8 9
  * quantile  (quantile) float64 0.25 0.5 0.75
&gt;&gt;&gt; np.nanpercentile(da_stacked, q=[25, 50, 75], axis=-1, interpolation='nearest')
array([[ 8.,  1.],
       [ 8.,  3.],
       [ 8.,  3.]])"><pre class="notranslate"><span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">out</span> <span class="pl-c1">=</span> <span class="pl-en">weighted_quantile</span>(<span class="pl-s1">da</span><span class="pl-c1">=</span><span class="pl-s1">ar</span>, <span class="pl-s1">q</span><span class="pl-c1">=</span>[<span class="pl-c1">0.25</span>, <span class="pl-c1">0.5</span>, <span class="pl-c1">0.75</span>], <span class="pl-s1">dim</span><span class="pl-c1">=</span>[<span class="pl-s">'x'</span>, <span class="pl-s">'y'</span>], <span class="pl-s1">w_dict</span><span class="pl-c1">=</span>{<span class="pl-s">'x'</span>: [<span class="pl-c1">1</span>, <span class="pl-c1">1</span>]}, <span class="pl-s1">interpolation</span><span class="pl-c1">=</span><span class="pl-s">'nearest'</span>)
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">out</span>
<span class="pl-c1">&lt;</span><span class="pl-s1">xarray</span>.<span class="pl-v">DataArray</span> (<span class="pl-s1">quantile</span>: <span class="pl-c1">3</span>, <span class="pl-s1">z</span>: <span class="pl-c1">2</span>)<span class="pl-c1">&gt;</span>
<span class="pl-en">array</span>([[ <span class="pl-c1">8.</span>,  <span class="pl-c1">1.</span>],
       [ <span class="pl-c1">8.</span>,  <span class="pl-c1">3.</span>],
       [ <span class="pl-c1">8.</span>,  <span class="pl-c1">3.</span>]])
<span class="pl-v">Coordinates</span>:
  <span class="pl-c1">*</span> <span class="pl-en">z</span>         (<span class="pl-s1">z</span>) <span class="pl-s1">int64</span> <span class="pl-c1">8</span> <span class="pl-c1">9</span>
  <span class="pl-c1">*</span> <span class="pl-en">quantile</span>  (<span class="pl-s1">quantile</span>) <span class="pl-s1">float64</span> <span class="pl-c1">0.25</span> <span class="pl-c1">0.5</span> <span class="pl-c1">0.75</span>
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">np</span>.<span class="pl-en">nanpercentile</span>(<span class="pl-s1">da_stacked</span>, <span class="pl-s1">q</span><span class="pl-c1">=</span>[<span class="pl-c1">25</span>, <span class="pl-c1">50</span>, <span class="pl-c1">75</span>], <span class="pl-s1">axis</span><span class="pl-c1">=</span><span class="pl-c1">-</span><span class="pl-c1">1</span>, <span class="pl-s1">interpolation</span><span class="pl-c1">=</span><span class="pl-s">'nearest'</span>)
<span class="pl-en">array</span>([[ <span class="pl-c1">8.</span>,  <span class="pl-c1">1.</span>],
       [ <span class="pl-c1">8.</span>,  <span class="pl-c1">3.</span>],
       [ <span class="pl-c1">8.</span>,  <span class="pl-c1">3.</span>]])</pre></div>
<p dir="auto">We wonder if it's ok to make this feature part of numpy, probably in <code class="notranslate">np.nanpercentile</code>?</p>