Skip to content

.pint.ito() not working #282

@etiennebresciani

Description

@etiennebresciani

Problem

Calling .pint.ito() from a Series object should allow for changing its units, but it just does nothing. Minimal reproducible example:

import pandas as pd
import pint_pandas

s = pd.Series([1.0, 2.0], dtype="pint[m]")
print(s)
s.pint.ito('cm')
print(s)

Output:

0    1.0
1    2.0
dtype: pint[meter][Float64]
0    1.0
1    2.0
dtype: pint[meter][Float64]

Origin

I figured out the problem arises in pint_array.DelegatedMethod.__get__(), where the called method (here ito()) is delegated to an instance of Quantity (created in pint_array.PintSeriesAccessor.__init__()) that is independent of the calling Series object. As a result, any inplace modification is lost.

Potential solution

A solution would consist in re-initializing the calling Series object with quantity magnitude and units after result = method(*args, **kwargs) in pint_array.DelegatedMethod.__get__(). I.e., add:

q = object.__getattribute__(obj, "quantity")
po = object.__getattribute__(obj, "pandas_obj")
dtype = PintType(units=q.units, subdtype=q.dtype)
po.__init__(q.magnitude, dtype=dtype)

Note that the change in units implies a change in the Series dtype, which is why a complete Series re-initialization is needed, and not just an update of the underlying PintArray data. With this modification, I get the expected output:

0    1.0
1    2.0
dtype: pint[meter][Float64]
0    100.0
1    200.0
dtype: pint[centimeter][float64]

Would this be good for a PR?

PS: if we only want to re-initialize when it is really necessary, we could imagine a solution with a new boolean attribute in the Delegated class such as reinitialize, which will be set to True only for those methods that require it. Let me know if you want me to work on a PR with that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions