I have two classified raster (snow cover % 10-100) one is prepared from coarse resolution and another is from finer resolution. I am doing accuracy assessment and matrix calculation of snow cover %. However, both classified raster has invalid classes like NoData (-9999), cloud (value=205), water (210), permanent ice(215).

Now both the raster has same pixel size after resampling and covering same area by using gdalwarp

These classes/values are effecting the accuracy assessment. I only want to comapre both raster in terms of snow cover %. How can I eliminate those value from both raster??

My code

#reading in array Snow cover % raster from true raster (finer resolution)
img= rasterio.open(filepath+'20020310_ndsi_reclass.tif')

#Reading in array Snow cover % from prediction raster (coarser resolution)
img_pre= rasterio.open(filepath+ '20020310_ndsi_reclass_pred.tif')

#making it 1dimesional
y_true= np.ravel(img_r)
y_pred= np.ravel(img_pre_r)
y_true = y_true.astype('int')
y_pred = y_pred.astype('int')

from sklearn import metrics
print(metrics.classification_report(y_true, y_pred))

the classification report

Matrix calculation

from sklearn.metrics import confusion_matrix

cm=confusion_matrix(y_true, y_pred)

import seaborn as sn
ax= plt.subplot()
sns.heatmap(cm, annot=True, ax = ax); #annot=True to annotate cells

# labels, title and ticks
ax.set_xlabel('Predicted labels');ax.set_ylabel('True labels'); 
ax.set_title('Confusion Matrix'); 
ax.xaxis.set_ticklabels(['nodata','0','10', '20', '30', '40', '50', '60', '70', '80', '90', '100', 'cloud', 'water', 'ice']); ax.yaxis.set_ticklabels(['nodata','0','10', '20', '30', '40', '50', '60', '70', '80', '90', '100', 'cloud', 'water', 'ice']);

plotting matrix How to exclude Nodata, cloud, water, and ice from both the report?

1 Answer 1


Take a look at np.where and maybe do something like:

y_true= np.ravel(img_r)
y_pred= np.ravel(img_pre_r)
y_true = y_true.astype('int')
y_pred = y_pred.astype('int')

indx = np.where((y_true != -9999) & (y_true != 205) & (y_true != 210) & (y_true != 215))

y_true = y_true[indx]
y_pred = y_pred[indx]

Or apply the np.where call to both true and pred arrays and use logical operators.

  • Thanks @Ryan it worked for me in this case where I converted 2D to 1D array. How can I make it work for normal raster 2d array? As I am doing zonal_stats from rasterstats [automating-gis-processes.github.io/CSC18/lessons/L6/… . Those invalid class is dominating the zonal statistic. I tried indx = np.where((y_true != -9999) & (y_true != 205) & (y_true != 210) & (y_true != 215)) y_true = y_true[indx] but it is making the array 1D however I need 2d array for this application.
    – Tua
    Feb 12, 2020 at 13:05
  • @Tua Check out the nan stats in numpy: nanmean, nanmedian, etc.. You can supply one or more of those functions to rasterstats as an add_stats argument.
    – Ryan
    Feb 12, 2020 at 16:31
  • there is no problem running in rasterstats however it is taking all those unwanted areas like (205, 210) and giving results accordingly. I meant to ask you that how can remove those unwanted value (like 205,210, etc) from 2D array the indx above is for 1D array how can I apply for this eliminating those unwanted values from 2D array? I have tried putting : but did not work
    – Tua
    Feb 13, 2020 at 8:02
  • 1
    @Tua you pass a 2D array to np.where like this: indx = np.where((img_r == 210.0) | (img_r == 205.0 )). And then index and reassign the array values directly: img_r[indx] = np.nan. And then pass it to rasterstats to with the nan functions.
    – Ryan
    Feb 13, 2020 at 16:36
  • Thank you so much for looking into it it worked :)
    – Tua
    Feb 14, 2020 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.