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

Upgrade to quantile function arising from pandas 1.3.0 internals change #170

Merged
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:

- name: Test with pytest
shell: bash -l {0}
run: pytest --cov=anesthetic -n auto tests
run: python -m pytest --cov=anesthetic -n auto tests

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
4 changes: 2 additions & 2 deletions anesthetic/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def compress_weights(w, u=None, nsamples=None):
return (integer + extra).astype(int)


def quantile(a, q, w=None):
def quantile(a, q, w=None, interpolation='linear'):
"""Compute the weighted quantile for a one dimensional array."""
if w is None:
w = np.ones_like(a)
Expand All @@ -78,7 +78,7 @@ def quantile(a, q, w=None):
c = np.cumsum(w[i[1:]]+w[i[:-1]])
c /= c[-1]
c = np.concatenate(([0.], c))
icdf = interp1d(c, a[i])
icdf = interp1d(c, a[i], kind=interpolation)
quant = icdf(q)
if isinstance(q, float):
quant = float(quant)
Expand Down
14 changes: 10 additions & 4 deletions anesthetic/weighted_pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,11 @@ def sem(self, skipna=True):
"""Weighted standard error of the mean."""
return np.sqrt(self.var(skipna=skipna)/self.neff())

def quantile(self, q=0.5):
def quantile(self, q=0.5, numeric_only=True, interpolation='linear'):
"""Weighted quantile of the sampled distribution."""
return quantile(self.values, q, self.weights)
if not numeric_only:
raise NotImplementedError("numeric_only kwarg not implemented")
return quantile(self.values, q, self.weights, interpolation)

def compress(self, nsamples=None):
"""Reduce the number of samples by discarding low-weights.
Expand Down Expand Up @@ -266,16 +268,20 @@ def sem(self, axis=0, skipna=True):
n = self.neff() if axis == 0 else self.shape[1]
return np.sqrt(self.var(axis=axis, skipna=skipna)/n)

def quantile(self, q=0.5, axis=0):
def quantile(self, q=0.5, axis=0, numeric_only=True,
interpolation='linear'):
"""Weighted quantile of the sampled distribution."""
if not numeric_only:
raise NotImplementedError("numeric_only kwarg not implemented")
if axis == 0:
data = np.array([c.quantile(q) for _, c in self.iteritems()])
if np.isscalar(q):
return Series(data, index=self.columns)
else:
return DataFrame(data.T, columns=self.columns, index=q)
else:
return super().quantile(q=q, axis=axis)
return super().quantile(q=q, axis=axis, numeric_only=numeric_only,
interpolation=interpolation)

def compress(self, nsamples=None):
"""Reduce the number of samples by discarding low-weights.
Expand Down
6 changes: 6 additions & 0 deletions tests/test_weighted_pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ def test_WeightedDataFrame_quantile():
quantile = df.quantile(qs, axis=1)
assert isinstance(quantile, WeightedDataFrame)

with pytest.raises(NotImplementedError):
df.quantile(numeric_only=False)


def test_WeightedDataFrame_hist():
plt.figure()
Expand Down Expand Up @@ -405,6 +408,9 @@ def test_WeightedSeries_quantile():

assert_allclose(series.quantile(qs), qs, atol=1e-2)

with pytest.raises(NotImplementedError):
series.quantile(numeric_only=False)


def test_WeightedSeries_hist():
plt.figure()
Expand Down