| 4001 | |
| 4002 | |
| 4003 | def _median(a, axis=None, out=None, overwrite_input=False): |
| 4004 | # can't be reasonably be implemented in terms of percentile as we have to |
| 4005 | # call mean to not break astropy |
| 4006 | a = np.asanyarray(a) |
| 4007 | |
| 4008 | # Set the partition indexes |
| 4009 | if axis is None: |
| 4010 | sz = a.size |
| 4011 | else: |
| 4012 | sz = a.shape[axis] |
| 4013 | if sz % 2 == 0: |
| 4014 | szh = sz // 2 |
| 4015 | kth = [szh - 1, szh] |
| 4016 | else: |
| 4017 | kth = [(sz - 1) // 2] |
| 4018 | |
| 4019 | # We have to check for NaNs (as of writing 'M' doesn't actually work). |
| 4020 | supports_nans = np.issubdtype(a.dtype, np.inexact) or a.dtype.kind in 'Mm' |
| 4021 | if supports_nans: |
| 4022 | kth.append(-1) |
| 4023 | |
| 4024 | if overwrite_input: |
| 4025 | if axis is None: |
| 4026 | part = a.ravel() |
| 4027 | part.partition(kth) |
| 4028 | else: |
| 4029 | a.partition(kth, axis=axis) |
| 4030 | part = a |
| 4031 | else: |
| 4032 | part = partition(a, kth, axis=axis) |
| 4033 | |
| 4034 | if part.shape == (): |
| 4035 | # make 0-D arrays work |
| 4036 | return part.item() |
| 4037 | if axis is None: |
| 4038 | axis = 0 |
| 4039 | |
| 4040 | indexer = [slice(None)] * part.ndim |
| 4041 | index = part.shape[axis] // 2 |
| 4042 | if part.shape[axis] % 2 == 1: |
| 4043 | # index with slice to allow mean (below) to work |
| 4044 | indexer[axis] = slice(index, index + 1) |
| 4045 | else: |
| 4046 | indexer[axis] = slice(index - 1, index + 1) |
| 4047 | indexer = tuple(indexer) |
| 4048 | |
| 4049 | # Use mean in both odd and even case to coerce data type, |
| 4050 | # using out array if needed. |
| 4051 | rout = mean(part[indexer], axis=axis, out=out) |
| 4052 | if supports_nans and sz > 0: |
| 4053 | # If nans are possible, warn and replace by nans like mean would. |
| 4054 | rout = np.lib._utils_impl._median_nancheck(part, rout, axis) |
| 4055 | |
| 4056 | return rout |
| 4057 | |
| 4058 | |
| 4059 | def _percentile_dispatcher(a, q, axis=None, out=None, overwrite_input=None, |