votes up 6

cannot assign mismatch length to masked array

Package:
pandas
github stars 30911
Exception Class:
ValueError

Raise code

            # `np.place` on the other hand uses the ``new`` values at it is
            # to place in the masked locations of ``values``
            np.place(values, mask, new)
            # i.e. values[mask] = new
        elif mask.shape[-1] == len(new) or len(new) == 1:
            np.putmask(values, mask, new)
        else:
            raise ValueError("cannot assign mismatch length to masked array")
    else:
        np.putmask(values, mask, new)


def validate_putmask(values: ArrayLike, mask: np.ndarray) -> Tuple[np.ndarray, bool]:
    """
    Validate mask and check if this putmask operation is a no-op. """

Ways to fix

votes up 1 votes down

Steps to reproduce:

Step 1: Create a new directory using the command

$ mkdir test-pandas

Step 2: Navigate to that our new directory using the command

$ cd test-pandas

Step 3: Run the following command

$ pipenv shell

Step 4: To reproduce the exception we need a pre-release version of pandas as the function putmask_without_repeat which can be used to reproduce the exception was introduced in the pre-release version 1.3.0rc1. To install this version of pandas run the following command:

$ pipenv install --pre pandas==1.3.0rc1

Step 5: Run the code:

from pandas.core.array_algos.putmask import putmask_without_repeat

import numpy as np


arr = np.arange(1, 10)
mask = arr > 5
new = arr ** 2

# Remove one element from the new list to make it 9 elements
new = np.delete(new, 0)

# Since, the array and new lsit has mismatched length i.e 10 and 9 resp. thus, exception is caused
putmask_without_repeat(arr, mask, new)
print(arr)

The above code raises the following exception:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-37-4223aa6afd21> in <module>()
     12 
     13 # Since, the array and new lsit has mismatched length i.e 10 and 9 resp. thus, exception is caused
---> 14 putmask_without_repeat(arr, mask, new)
     15 print(arr)

/usr/local/lib/python3.7/dist-packages/pandas/core/array_algos/putmask.py in putmask_without_repeat(values, mask, new)
    166             np.putmask(values, mask, new)
    167         else:
--> 168             raise ValueError("cannot assign mismatch length to masked array")
    169     else:
    170         np.putmask(values, mask, new)

ValueError: cannot assign mismatch length to masked array

Fixed version of code:

from pandas.core.array_algos.putmask import putmask_without_repeat

import numpy as np


arr = np.arange(1, 10)
mask = arr > 5
new = arr ** 2

putmask_without_repeat(arr, mask, new)
print(arr)

Explanation:

The pandas putmask_without_repeat function takes three positional arguments namely arr, mask and new. If the new argument specified is a list then, its length should be either 1 or equal to the length of the array supplied. Else, both will have a mismatch length and the exception will be raised. The new argument can take other values like int or float as well.

Jun 18, 2021 umangtaneja98 answer

Add a possible fix

Please authorize to post fix