Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug report: broadcasted weights with NaN lead to ValueError: assignment destination is read-only #79

Closed
ahuang11 opened this issue Mar 14, 2020 · 3 comments
Labels
bug Something isn't working

Comments

@ahuang11
Copy link
Member

import xarray as xr
import numpy as np
import pandas as pd
import xskillscore as xs

obs2 = xr.DataArray(
    np.random.rand(3, 180, 360),
    coords=[
        pd.date_range("1/1/2000", "1/3/2000", freq="D"),
        np.linspace(-89.5, 89.5, 180),
        np.linspace(-179.5, 179.5, 360),
    ],
    dims=["time", "lat", "lon"],
 )
obs2 = obs2.where(obs2 > 0.6)

fct2 = obs2.copy()
fct2.values = np.random.rand(3, 180, 360)
fct2 = fct2.where(fct2 < 0.25)

# make weights as cosine of the latitude and broadcast
weights = np.cos(np.deg2rad(obs2.lat))
_, weights = xr.broadcast(obs2, weights)
# Remove the time dimension from weights
weights = weights.isel(time=0)

xs.rmse(obs2, fct2, ['lat', 'lon'], weights=weights, skipna=True)

~/anaconda3/envs/py3/lib/python3.7/site-packages/xskillscore/core/np_deterministic.py in _match_nans(a, b, weights)
     37         a[idx], b[idx] = np.nan, np.nan
     38         if weights is not None:
---> 39             weights[idx] = np.nan
     40     return a, b, weights
     41 

ValueError: assignment destination is read-only

@raybellwaves
Copy link
Member

Full stack trace

In [8]: xs.rmse(obs2, fct2, ['lat', 'lon'], weights=weights, skipna=True)                                                                    
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-922ccbf3baf3> in <module>
----> 1 xs.rmse(obs2, fct2, ['lat', 'lon'], weights=weights, skipna=True)

~/local/bin/anaconda3/envs/xss/lib/python3.6/site-packages/xskillscore/core/deterministic.py in rmse(a, b, dim, weights, skipna)
    632         kwargs={"axis": axis, "skipna": skipna},
    633         dask="parallelized",
--> 634         output_dtypes=[float],
    635     )
    636 

~/local/bin/anaconda3/envs/xss/lib/python3.6/site-packages/xarray/core/computation.py in apply_ufunc(func, input_core_dims, output_core_dims, exclude_dims, vectorize, join, dataset_join, dataset_fill_value, keep_attrs, kwargs, dask, output_dtypes, output_sizes, meta, *args)
   1062             join=join,
   1063             exclude_dims=exclude_dims,
-> 1064             keep_attrs=keep_attrs,
   1065         )
   1066     elif any(isinstance(a, Variable) for a in args):

~/local/bin/anaconda3/envs/xss/lib/python3.6/site-packages/xarray/core/computation.py in apply_dataarray_vfunc(func, signature, join, exclude_dims, keep_attrs, *args)
    231 
    232     data_vars = [getattr(a, "variable", a) for a in args]
--> 233     result_var = func(*data_vars)
    234 
    235     if signature.num_outputs > 1:

~/local/bin/anaconda3/envs/xss/lib/python3.6/site-packages/xarray/core/computation.py in apply_variable_ufunc(func, signature, exclude_dims, dask, output_dtypes, output_sizes, keep_attrs, meta, *args)
    602                 "apply_ufunc: {}".format(dask)
    603             )
--> 604     result_data = func(*input_data)
    605 
    606     if signature.num_outputs == 1:

~/local/bin/anaconda3/envs/xss/lib/python3.6/site-packages/xskillscore/core/np_deterministic.py in _rmse(a, b, weights, axis, skipna)
    447     sumfunc, meanfunc = _get_numpy_funcs(skipna)
    448     if skipna:
--> 449         a, b, weights = _match_nans(a, b, weights)
    450     weights = _check_weights(weights)
    451 

~/local/bin/anaconda3/envs/xss/lib/python3.6/site-packages/xskillscore/core/np_deterministic.py in _match_nans(a, b, weights)
     37         a[idx], b[idx] = np.nan, np.nan
     38         if weights is not None:
---> 39             weights[idx] = np.nan
     40     return a, b, weights
     41 

ValueError: assignment destination is read-only

@raybellwaves raybellwaves added the bug Something isn't working label Mar 15, 2020
@raybellwaves
Copy link
Member

Closed via #81

@aaronspring
Copy link
Collaborator

I dont understand what that test here checks:

@pytest.fixture
def a_3d():
    da = xr.DataArray(
        np.repeat(np.array([[0, 1, 2], [4, 5, 6], [7, 8, 9]]), 3).reshape(3, 3, 3),
        coords=[
            xr.cftime_range('2000-01-01', '2000-01-03', freq='D'),
            np.linspace(-89.5, 89.5, 3),
            np.linspace(-179.5, 179.5, 3),
        ],
        dims=['time', 'lat', 'lon'],
    )
    return da


@pytest.fixture
def b_3d(a_3d):
    return a_3d.copy()

@pytest.mark.parametrize('metric', WEIGHTED_METRICS)
def test_skipna_broadcast_weights_assignment_destination(
    a_3d, b_3d, weights_lonlat, metric
):
    """Tests that 'assignment destination is read-only' is not raised
    https://github.com/raybellwaves/xskillscore/issues/79"""
    a_3d_nan = a_3d.where(a_3d > 0)
    b_3d_nan = b_3d.where(b_3d > 0)
    res = metric(a_3d_nan, b_3d_nan, ['lat', 'lon'], weights=weights_lonlat, skipna=True)
    assert all([not np.isnan(r) for r in res])

I see here that a metric checks to identical arrays agains each other, which would not make too much sense.

Tried to refactor this in #159

@aaronspring aaronspring mentioned this issue Aug 28, 2020
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants