Determine how a param is being set as readonly

I have a class similar to the example below

class P(param.Parameterized):
    a = param.Array()
    r = param.Array()
    d = param.DataFrame()
    
    def setup(self):
        axis_names = [f"Axis_{i+1}" for i in range(5)]
        dt = np.dtype([('expected', 'i4'), ('actual', 'i4')])
        self.a = np.random.randint(0,100, (10,10))
        
        comp_dt_lst = [(ax, dt) for ax in axis_names]
        self.dtype = np.dtype(comp_dt_lst)
        self.r = self.a.view(self.dtype, np.recarray)
        
        cnames = []
        for axis_name in axis_names:
            cnames.extend([i for i in itertools.product((axis_name,), dt.names)])
        print(cnames)
        
        # Set the pandas.DataFrame column indexs to the column tuples.
        columns = pd.MultiIndex.from_tuples(cnames)

        # This makes a MultiIndex which is supported in pandas but is not supported in param and panel libraries for
        # dynamic viewing. For that reason the next few lines of code with compress the MultiIndex columns into a single
        # set of columns with the form 'AxisName_SampleName'
        df = pd.DataFrame(self.a,
                          columns=columns
                          )
        df.columns = ["_".join(col) for col in df.columns]
        # TODO: We can set a flag later to use the MultiIndex columns or the flat columns when param and panel supports
        #       that tye of indexing.
        self.d = df

I’m using this basic example to test the usage pattern where I store a numpy.ndarray once but keep both a numpy recarray and pandas Dataframe view of the same data to allow for different access patterns a viewing with panel without duplicating the large array in memory.

this example works as you can see from the example below

However I have this same basic pattern in a much larger class but when I try to assign a value to the main numpy array I get a ValueError: assignment destination is read-only. I have not declared any of the paramerters in param.Parameterized class as readonly or constant but continue to get this simple ValueError.

Is there a way to track down were the readonly designation is being applied via some other more detailed stack trace? I’m beyond frustrated with trying ot figure out why the main array is being assigned as readonly when I have made no such designation in my code.

I have found the source of my error. It appears this is an issue associated with reading numpy arrays from a buffer not with the parameters themselves.

Hopefully this helps someone avoid a couple of days of frustrating searching in the future.

If you read a numpy array in from a buffer and would like to manipulate the values across views add a .copy() to the end of the initial read so that the array is not set as read-only.

1 Like

Just out of curiosity, did the error message (ValueError: assignment ...) have anything to do with Param itself?

No. I have been really impressed with param so I’m rewriting my old code into param.Parameterized classes to better document the purpose of the code and to take advantage of the visualization capabilities of panel. One of the features I was using in Jupyter as I get better at parm and panel was the with param.exceptions_summarized(): context manager.

I mistakenly thought this context manager would only summarize the param related exceptions since the code was previously working as non-param classes. The ValueError was the only thing being dumped out so I assumed it was a param related error. Once I removed the context manager and explored the full trace I found the numpy related issue. This more a gap in my understanding than a real issue with any one library.

Thanks for all the help. My 2022 resolution is to get all my code into param and panel related classes so I’m sure I will be pestering everyone with issues that may end up being more me than the libraries themselves. Merry Christmas!

2 Likes

Param is indeed a powerful library! People should write more code using it to make their life easier and their user experience better :wink:

I believe exceptions_summarized was added to param purely to write the documentation, it’s useful to only print the error message of an instead long and boring exception traceback, exception that would stop the notebook execution. But in your code you should definitely not use it since it will skip exceptions. This context manager would be better off in a separate module dedicated to the docs.