Compare self with other using operator.eq or operator.ne. When either of the elements is masked, the result is masked as well, but the underlying boolean data are still set, with self and other considered equal if both are masked, and unequal otherwise. For structur
(self, other, compare)
| 4191 | return array_ufunc is None |
| 4192 | |
| 4193 | def _comparison(self, other, compare): |
| 4194 | """Compare self with other using operator.eq or operator.ne. |
| 4195 | |
| 4196 | When either of the elements is masked, the result is masked as well, |
| 4197 | but the underlying boolean data are still set, with self and other |
| 4198 | considered equal if both are masked, and unequal otherwise. |
| 4199 | |
| 4200 | For structured arrays, all fields are combined, with masked values |
| 4201 | ignored. The result is masked if all fields were masked, with self |
| 4202 | and other considered equal only if both were fully masked. |
| 4203 | """ |
| 4204 | omask = getmask(other) |
| 4205 | smask = self.mask |
| 4206 | mask = mask_or(smask, omask, copy=True) |
| 4207 | |
| 4208 | odata = getdata(other) |
| 4209 | if mask.dtype.names is not None: |
| 4210 | # only == and != are reasonably defined for structured dtypes, |
| 4211 | # so give up early for all other comparisons: |
| 4212 | if compare not in (operator.eq, operator.ne): |
| 4213 | return NotImplemented |
| 4214 | # For possibly masked structured arrays we need to be careful, |
| 4215 | # since the standard structured array comparison will use all |
| 4216 | # fields, masked or not. To avoid masked fields influencing the |
| 4217 | # outcome, we set all masked fields in self to other, so they'll |
| 4218 | # count as equal. To prepare, we ensure we have the right shape. |
| 4219 | broadcast_shape = np.broadcast(self, odata).shape |
| 4220 | sbroadcast = np.broadcast_to(self, broadcast_shape, subok=True) |
| 4221 | sbroadcast._mask = mask |
| 4222 | sdata = sbroadcast.filled(odata) |
| 4223 | # Now take care of the mask; the merged mask should have an item |
| 4224 | # masked if all fields were masked (in one and/or other). |
| 4225 | mask = (mask == np.ones((), mask.dtype)) |
| 4226 | # Ensure we can compare masks below if other was not masked. |
| 4227 | if omask is np.False_: |
| 4228 | omask = np.zeros((), smask.dtype) |
| 4229 | |
| 4230 | else: |
| 4231 | # For regular arrays, just use the data as they come. |
| 4232 | sdata = self.data |
| 4233 | |
| 4234 | check = compare(sdata, odata) |
| 4235 | |
| 4236 | if isinstance(check, (np.bool, bool)): |
| 4237 | return masked if mask else check |
| 4238 | |
| 4239 | if mask is not nomask: |
| 4240 | if compare in (operator.eq, operator.ne): |
| 4241 | # Adjust elements that were masked, which should be treated |
| 4242 | # as equal if masked in both, unequal if masked in one. |
| 4243 | # Note that this works automatically for structured arrays too. |
| 4244 | # Ignore this for operations other than `==` and `!=` |
| 4245 | check = np.where(mask, compare(smask, omask), check) |
| 4246 | |
| 4247 | if mask.shape != check.shape: |
| 4248 | # Guarantee consistency of the shape, making a copy since the |
| 4249 | # the mask may need to get written to later. |
| 4250 | mask = np.broadcast_to(mask, check.shape).copy() |
no test coverage detected