Numpy support#
Numpy functions that work on pint Quantity ndarray objects also work on PintArray.
In [1]: pa = PintArray([1, 2, np.nan, 4, 10], dtype="pint[m]")
In [2]: np.clip(pa, 3 * ureg.m, 5 * ureg.m)
Out[2]:
<PintArray>
[3.0, 3.0, <NA>, 4.0, 5.0]
Length: 5, dtype: pint[meter][Float64]
Note that this function errors when applied to a Series.
In [3]: df = pd.DataFrame({"A": pa})
In [4]: np.clip(df['A'], 3 * ureg.m, 5 * ureg.m)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[4], line 1
----> 1 np.clip(df['A'], 3 * ureg.m, 5 * ureg.m)
File ~/checkouts/readthedocs.org/user_builds/pint-pandas-michaeltiemannosc/envs/latest/lib/python3.11/site-packages/pint/facets/numpy/quantity.py:75, in NumpyQuantity.__array_function__(self, func, types, args, kwargs)
74 def __array_function__(self, func, types, args, kwargs):
---> 75 return numpy_wrap("function", func, args, kwargs, types)
File ~/checkouts/readthedocs.org/user_builds/pint-pandas-michaeltiemannosc/envs/latest/lib/python3.11/site-packages/pint/facets/numpy/numpy_func.py:1112, in numpy_wrap(func_type, func, args, kwargs, types)
1110 if name not in handled or any(is_upcast_type(t) for t in types):
1111 return NotImplemented
-> 1112 return handled[name](*args, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/pint-pandas-michaeltiemannosc/envs/latest/lib/python3.11/site-packages/pint/facets/numpy/numpy_func.py:874, in implement_consistent_units_by_argument.<locals>.implementation(*args, **kwargs)
872 for i, unwrapped_unit_arg in enumerate(unwrapped_unit_args):
873 bound_args.arguments[valid_unit_arguments[i]] = unwrapped_unit_arg
--> 874 ret = func(*bound_args.args, **bound_args.kwargs)
876 # Conditionally wrap output
877 if wrap_output:
File ~/checkouts/readthedocs.org/user_builds/pint-pandas-michaeltiemannosc/envs/latest/lib/python3.11/site-packages/numpy/_core/fromnumeric.py:2330, in clip(a, a_min, a_max, out, min, max, **kwargs)
2326 elif min is not np._NoValue or max is not np._NoValue:
2327 raise ValueError("Passing `min` or `max` keyword argument when "
2328 "`a_min` and `a_max` are provided is forbidden.")
-> 2330 return _wrapfunc(a, 'clip', a_min, a_max, out=out, **kwargs)
File ~/checkouts/readthedocs.org/user_builds/pint-pandas-michaeltiemannosc/envs/latest/lib/python3.11/site-packages/numpy/_core/fromnumeric.py:54, in _wrapfunc(obj, method, *args, **kwds)
52 bound = getattr(obj, method, None)
53 if bound is None:
---> 54 return _wrapit(obj, method, *args, **kwds)
56 try:
57 return bound(*args, **kwds)
File ~/checkouts/readthedocs.org/user_builds/pint-pandas-michaeltiemannosc/envs/latest/lib/python3.11/site-packages/numpy/_core/fromnumeric.py:46, in _wrapit(obj, method, *args, **kwds)
43 # As this already tried the method, subok is maybe quite reasonable here
44 # but this follows what was done before. TODO: revisit this.
45 arr, = conv.as_arrays(subok=False)
---> 46 result = getattr(arr, method)(*args, **kwds)
48 return conv.wrap(result, to_scalar=False)
File ~/checkouts/readthedocs.org/user_builds/pint-pandas-michaeltiemannosc/envs/latest/lib/python3.11/site-packages/numpy/_core/_methods.py:115, in _clip(a, min, max, out, **kwargs)
113 return um.maximum(a, min, out=out, **kwargs)
114 else:
--> 115 return um.clip(a, min, max, out=out, **kwargs)
File pandas/_libs/missing.pyx:392, in pandas._libs.missing.NAType.__bool__()
TypeError: boolean value of NA is ambiguous
Apply the function to the PintArray instead of the Series using Series.values.
In [5]: np.clip(df['A'].values, 3 * ureg.m, 5 * ureg.m)
Out[5]:
<PintArray>
[3.0, 3.0, <NA>, 4.0, 5.0]
Length: 5, dtype: pint[meter][Float64]