我们从Python开源项目中,提取了以下45个代码示例,用于说明如何使用numpy.place()。
def set_nodata(self, data_name, new_nodata, old_nodata=None): """ Change nodata value of a dataset. Parameters ---------- data_name : string Attribute name of dataset to change. new_nodata : int or float New nodata value to use. old_nodata : int or float (optional) If none provided, defaults to self.grid_props[data_name]['nodata'] """ if old_nodata is None: old_nodata = self.grid_props[data_name]['nodata'] data = getattr(self, data_name) np.place(data, data == old_nodata, new_nodata) self.grid_props[data_name]['nodata'] = new_nodata
def select_subclassdata(X, y,totalClassNum,SubClassNum, subClassIndexList,normalize=True): X= np.array(list(itertools.compress(X, [subClassIndexList.__contains__(c) for c in y]))) y= np.array(list(itertools.compress(y, [subClassIndexList.__contains__(c) for c in y]))) d = {} for i in xrange(SubClassNum): d.update({subClassIndexList[i]: (totalClassNum+i)}) d1 = {} for i in xrange(SubClassNum): d1.update({(totalClassNum+i): i}) for k, v in d.iteritems(): np.place(y,y==k,v) for k, v in d1.iteritems(): np.place(y,y==k,v) return X,y
def process_data(coords, nbr_idx, elements): num_atoms = len(nbr_idx) # truncates off zero padding at the end and maps atomic numbers to atom types coords = coords[:num_atoms, :] elements = np.array([atom_dictionary[elements[i]] for i in range(num_atoms)], dtype=np.int32) # pad the neighbor indices with zeros if not enough neighbors elements = np.append(elements, 0) for i in range(num_atoms): if len(nbr_idx[i]) < 12: nbr_idx[i].extend(np.ones([12-len(nbr_idx[i])], dtype=np.int32) * num_atoms) nbr_idx = np.array([nbr_idx[i] for i in range(num_atoms)], dtype=np.int32) # creates neighboring atom type matrix - 0 = nonexistent atom nbr_atoms = np.take(elements, nbr_idx) np.place(nbr_idx, nbr_idx >= num_atoms, 0) elements = elements[:-1] return (coords.astype(np.float32), nbr_idx.astype(np.int32), elements.astype(np.int32), nbr_atoms.astype(np.int32))
def binarise_a_matrix(in_matrix, labels=None, dtype=np.bool): """ All the values above zeros will be ones. :param in_matrix: any matrix :param labels: input labels. :param dtype: the output matrix is forced to this data type (bool by default). :return: The same matrix, where all the non-zero elements are equals to 1. """ out_matrix = np.zeros_like(in_matrix) if labels is None: non_zero_places = in_matrix != 0 else: non_zero_places = np.zeros_like(in_matrix, dtype=np.bool) for l in labels: non_zero_places += in_matrix == l np.place(out_matrix, non_zero_places, 1) return out_matrix.astype(dtype) # ---- Command executions utils ----
def grafting(im_hosting, im_patch, im_patch_mask=None): """ Take an hosting image, an image patch and a patch mask (optional) of the same dimension and in the same real space. It crops the patch (or patch mask if present) on the hosting image, and substitute the value from the patch. :param im_hosting: :param im_patch: :param im_patch_mask: :return: """ np.testing.assert_array_equal(im_hosting.affine, im_patch.affine) if im_patch_mask is not None: np.testing.assert_array_equal(im_hosting.affine, im_patch_mask.affine) if im_patch_mask is None: patch_region = im_patch.get_data().astype(np.bool) else: patch_region = im_patch_mask.get_data().astype(np.bool) new_data = np.copy(im_hosting.get_data()) new_data[patch_region] = im_patch.get_data()[patch_region] # np.place(new_data, patch_region, im_patch.get_data()) return set_new_data(im_hosting, new_data)
def intensity_segmentation(in_data, num_levels=5): """ :param in_data: image data in a numpy array. :param num_levels: maximum allowed 65535 - 1. :return: segmentation of the result in levels levels based on the intensities of the in_data. """ # NOTE: right extreme is excluded, must be considered in outside the for loop. segm = np.zeros_like(in_data, dtype=np.uint16) min_data = np.min(in_data) max_data = np.max(in_data) h = (max_data - min_data) / float(int(num_levels)) for k in xrange(0, num_levels): places = (min_data + k * h <= in_data) * (in_data < min_data + (k + 1) * h) np.place(segm, places, k) places = in_data == max_data np.place(segm, places, num_levels-1) return segm
def rescale(data, _min, _max, start=0.0, end=1.0, axis=0): """Rescale features of a dataset args: data (np.array): feature matrix. _min (np.array): list of minimum values per feature. _max (np.array): list of maximum values per feature. start (float = 0.): lowest value for norm. end (float = 1.): highest value for norm. axis (int = 0): axis to normalize across returns: (np.array): normalized features, the same shape as data """ new_data = (data - _min) / (_max - _min) # check if feature is constant, will be nan in new_data np.place(new_data, np.isnan(new_data), 1) new_data = (end - start) * new_data + start return new_data
def binary_seeds_from_distance_transform(distance_to_membrane, smoothingSigma, out_debug_image_dict): """ Return a binary image indicating the local maxima of the given distance transform. If smoothingSigma is provided, pre-smooth the distance transform before locating local maxima. """ # Can't work in-place: Not allowed to modify input distance_to_membrane = distance_to_membrane.copy() if smoothingSigma != 0.0: distance_to_membrane = vigra.filters.gaussianSmoothing(distance_to_membrane, smoothingSigma, out=distance_to_membrane) save_debug_image('smoothed DT for seeds', distance_to_membrane, out_debug_image_dict) localMaximaND(distance_to_membrane, allowPlateaus=True, allowAtBorder=True, marker=numpy.nan, out=distance_to_membrane) seedsVolume = numpy.isnan(distance_to_membrane) save_debug_image('binary seeds', seedsVolume.view(numpy.uint8), out_debug_image_dict) return seedsVolume
def place(arr, mask, vals): """ Change elements of an array based on conditional and input values. Similar to ``np.copyto(arr, vals, where=mask)``, the difference is that `place` uses the first N elements of `vals`, where N is the number of True values in `mask`, while `copyto` uses the elements where `mask` is True. Note that `extract` does the exact opposite of `place`. Parameters ---------- arr : ndarray Array to put data into. mask : array_like Boolean mask array. Must have the same size as `a`. vals : 1-D sequence Values to put into `a`. Only the first N elements are used, where N is the number of True values in `mask`. If `vals` is smaller than N it will be repeated. See Also -------- copyto, put, take, extract Examples -------- >>> arr = np.arange(6).reshape(2, 3) >>> np.place(arr, arr>2, [44, 55]) >>> arr array([[ 0, 1, 2], [44, 55, 44]]) """ if not isinstance(arr, np.ndarray): raise TypeError("argument 1 must be numpy.ndarray, " "not {name}".format(name=type(arr).__name__)) return _insert(arr, mask, vals)
def add_newdoc(place, obj, doc): """ Adds documentation to obj which is in module place. If doc is a string add it to obj as a docstring If doc is a tuple, then the first element is interpreted as an attribute of obj and the second as the docstring (method, docstring) If doc is a list, then each element of the list should be a sequence of length two --> [(method1, docstring1), (method2, docstring2), ...] This routine never raises an error. This routine cannot modify read-only docstrings, as appear in new-style classes or built-in functions. Because this routine never raises an error the caller must check manually that the docstrings were changed. """ try: new = getattr(__import__(place, globals(), {}, [obj]), obj) if isinstance(doc, str): add_docstring(new, doc.strip()) elif isinstance(doc, tuple): add_docstring(getattr(new, doc[0]), doc[1].strip()) elif isinstance(doc, list): for val in doc: add_docstring(getattr(new, val[0]), val[1].strip()) except: pass # Based on scitools meshgrid
def get_normalized_data(): print "Reading in and transforming data..." df = pd.read_csv('../large_files/train.csv') data = df.as_matrix().astype(np.float32) np.random.shuffle(data) X = data[:, 1:] mu = X.mean(axis=0) std = X.std(axis=0) np.place(std, std == 0, 1) X = (X - mu) / std # normalize the data Y = data[:, 0] return X, Y
def process_do(self, sub_batch_T, Thetas, cost_queue=None, queue=None, max_action_value_queue=None): """ sub_batch_T contains: S_A_features, A, R, S'_As_features, isTerminate """ # all_S_A_features: shape(sample num, features num) all_S_A_features = np.array([A for A in sub_batch_T['S_A_features'].values]).squeeze(2).T all_Q = self.get_Q(all_S_A_features, Thetas) # all_y_predict: shape(sample num, 1) all_y_predict = all_Q # all_next_S_As_features: shape(sample num, (features num, all_actions) ) all_next_S_As_features = sub_batch_T["S'_As_features"].values all_next_Q_max = self.get_next_Q_max(all_next_S_As_features) # all_isTerminate: shape(sample num, 1) all_isTerminate = sub_batch_T['isTerminate'][:, np.newaxis] # next_Q_max = 0 if it's terminate state np.place(all_next_Q_max, all_isTerminate, 0) all_reward = sub_batch_T['R'][:, np.newaxis] # all_y: shape(sample num, 1) all_y = all_reward + self.gamma * all_next_Q_max Gradients = self.get_gradients_back_propagate(all_y, all_y_predict, Thetas) thetas_sum = 0 for thetas in self.Thetas: thetas_sum += np.square(thetas[1:, :]).sum(0).sum() cost = 1 / (2 * len(sub_batch_T)) * \ (np.square(all_y-all_y_predict).sum(0).sum() + self.lambda_reg * thetas_sum) max_action_value = np.max(all_next_Q_max) print('Max action value: ', max_action_value) if queue == None and cost_queue == None: return [Gradients, cost, max_action_value] else: queue.put(Gradients) cost_queue.put(cost) max_action_value_queue.put(max_action_value)
def calculate_AFD(self, A, layer): X = A.copy() if layer < self.n_layers-1: if self.activation_function == 'ReLU': np.place(X, np.array(X > 0), 1) d = X.clip(0) elif self.activation_function == 'SoftPlus': d = 1/(1 + np.exp(-X)) else: raise NameError(self.activation_function, ' is not in the name list') else: d = np.ones_like(X) return d
def relabeller(in_data, list_old_labels, list_new_labels, verbose=True): """ :param in_data: array corresponding to an image segmentation. :param list_old_labels: list or tuple of labels :param list_new_labels: list or tuple of labels of the same len as list_old_labels :param verbose: :return: array where all the labels in list_new_labels are substituted with list_new_label in the same order. """ if isinstance(list_new_labels, int): list_new_labels = [list_new_labels, ] if isinstance(list_old_labels, int): list_old_labels = [list_old_labels, ] # sanity check: old and new have the same number of elements if not len(list_old_labels) == len(list_new_labels): raise IOError('Labels list does not have the same length.') new_data = copy.deepcopy(in_data) for k in range(len(list_new_labels)): places = in_data == list_old_labels[k] if np.any(places): np.place(new_data, places, list_new_labels[k]) if verbose: print('Label {0} substituted with label {1}'.format(list_old_labels[k], list_new_labels[k])) else: print('Label {0} not present in the array'.format(list_old_labels[k])) return new_data
def place(arr, mask, vals): """ Change elements of an array based on conditional and input values. Similar to ``np.copyto(arr, vals, where=mask)``, the difference is that `place` uses the first N elements of `vals`, where N is the number of True values in `mask`, while `copyto` uses the elements where `mask` is True. Note that `extract` does the exact opposite of `place`. Parameters ---------- arr : array_like Array to put data into. mask : array_like Boolean mask array. Must have the same size as `a`. vals : 1-D sequence Values to put into `a`. Only the first N elements are used, where N is the number of True values in `mask`. If `vals` is smaller than N it will be repeated. See Also -------- copyto, put, take, extract Examples -------- >>> arr = np.arange(6).reshape(2, 3) >>> np.place(arr, arr>2, [44, 55]) >>> arr array([[ 0, 1, 2], [44, 55, 44]]) """ return _insert(arr, mask, vals)
def add_newdoc(place, obj, doc): """Adds documentation to obj which is in module place. If doc is a string add it to obj as a docstring If doc is a tuple, then the first element is interpreted as an attribute of obj and the second as the docstring (method, docstring) If doc is a list, then each element of the list should be a sequence of length two --> [(method1, docstring1), (method2, docstring2), ...] This routine never raises an error. This routine cannot modify read-only docstrings, as appear in new-style classes or built-in functions. Because this routine never raises an error the caller must check manually that the docstrings were changed. """ try: new = getattr(__import__(place, globals(), {}, [obj]), obj) if isinstance(doc, str): add_docstring(new, doc.strip()) elif isinstance(doc, tuple): add_docstring(getattr(new, doc[0]), doc[1].strip()) elif isinstance(doc, list): for val in doc: add_docstring(getattr(new, val[0]), val[1].strip()) except: pass # Based on scitools meshgrid
def GetBatchVocab(words): batch_vocab = np.unique(words) words_remapped = np.copy(words) for i in xrange(len(batch_vocab)): np.place(words_remapped, words==batch_vocab[i], i) return batch_vocab, words_remapped
def derampGMatrix(displ): """ Deramp through lsq a bilinear plane Data is also de-meaned """ if displ.ndim != 2: raise TypeError('Displacement has to be 2-dim array') # form a relative coordinate grid c_grid = num.mgrid[0:displ.shape[0], 0:displ.shape[1]] # separate and flatten coordinate grid into x and y vectors for each !point ix = c_grid[0].flat iy = c_grid[1].flat displ_f = displ.flat # reduce vectors taking out all NaN's displ_nonan = displ_f[num.isfinite(displ_f)] ix = ix[num.isfinite(displ_f)] iy = iy[num.isfinite(displ_f)] # form kernel/design derampMatrix (c, x, y) GT = num.matrix([num.ones(len(ix)), ix, iy]) G = GT.T # generalized kernel matrix (quadtratic) GTG = GT * G # generalized inverse GTGinv = GTG.I # lsq estimates of ramp parameter ramp_paras = displ_nonan * (GTGinv * GT).T # ramp values ramp_nonan = ramp_paras * GT ramp_f = num.multiply(displ_f, 0.) # insert ramp values in full vectors num.place(ramp_f, num.isfinite(displ_f), num.array(ramp_nonan).flatten()) ramp_f = ramp_f.reshape(displ.shape[0], displ.shape[1]) return displ - ramp_f
def remove_wrongly_sized_connected_components(a, min_size, max_size=None, in_place=False, bin_out=False): """ Given a label image remove (set to zero) labels whose count is too low or too high. (Copied from lazyflow.) """ original_dtype = a.dtype if not in_place: a = a.copy() if min_size == 0 and (max_size is None or max_size > numpy.prod(a.shape)): # shortcut for efficiency if (bin_out): numpy.place(a,a,1) return a component_sizes = vigra_bincount(a) bad_sizes = component_sizes < min_size if max_size is not None: numpy.logical_or( bad_sizes, component_sizes > max_size, out=bad_sizes ) del component_sizes bad_locations = bad_sizes[a] a[bad_locations] = 0 del bad_locations if (bin_out): # Replace non-zero values with 1 numpy.place(a,a,1) return numpy.asarray(a, dtype=original_dtype)
def place(arr, mask, vals): """ Change elements of an array based on conditional and input values. Similar to ``np.copyto(arr, vals, where=mask)``, the difference is that `place` uses the first N elements of `vals`, where N is the number of True values in `mask`, while `copyto` uses the elements where `mask` is True. Note that `extract` does the exact opposite of `place`. Parameters ---------- arr : ndarray Array to put data into. mask : array_like Boolean mask array. Must have the same size as `a`. vals : 1-D sequence Values to put into `a`. Only the first N elements are used, where N is the number of True values in `mask`. If `vals` is smaller than N, it will be repeated, and if elements of `a` are to be masked, this sequence must be non-empty. See Also -------- copyto, put, take, extract Examples -------- >>> arr = np.arange(6).reshape(2, 3) >>> np.place(arr, arr>2, [44, 55]) >>> arr array([[ 0, 1, 2], [44, 55, 44]]) """ if not isinstance(arr, np.ndarray): raise TypeError("argument 1 must be numpy.ndarray, " "not {name}".format(name=type(arr).__name__)) return _insert(arr, mask, vals)
def _update_dim_sizes(dim_sizes, arg, core_dims): """ Incrementally check and update core dimension sizes for a single argument. Arguments --------- dim_sizes : Dict[str, int] Sizes of existing core dimensions. Will be updated in-place. arg : ndarray Argument to examine. core_dims : Tuple[str, ...] Core dimensions for this argument. """ if not core_dims: return num_core_dims = len(core_dims) if arg.ndim < num_core_dims: raise ValueError( '%d-dimensional argument does not have enough ' 'dimensions for all core dimensions %r' % (arg.ndim, core_dims)) core_shape = arg.shape[-num_core_dims:] for dim, size in zip(core_dims, core_shape): if dim in dim_sizes: if size != dim_sizes[dim]: raise ValueError( 'inconsistent size for core dimension %r: %r vs %r' % (dim, size, dim_sizes[dim])) else: dim_sizes[dim] = size
def normalize_reflectance_within_image(rast, nodata=-9999, scale=100): ''' Following Wu (2004, Remote Sensing of Environment), normalizes the reflectances in each pixel by the average reflectance *across bands.* This is an attempt to mitigate within-endmember variability. Arguments: rast A gdal.Dataset or numpy.array instance nodata The NoData value to use (and value to ignore) scale (Optional) Wu's definition scales the normalized reflectance by 100 for some reason; another reasonable value would be 10,000 (approximating scale of Landsat reflectance units); set to None for no scaling. ''' # Can accept either a gdal.Dataset or numpy.array instance if not isinstance(rast, np.ndarray): rastr = rast.ReadAsArray() else: rastr = rast.copy() shp = rastr.shape rastr_normalized = np.divide( rastr.reshape((shp[0], shp[1]*shp[2])), rastr.mean(axis=0).reshape((1, shp[1]*shp[2])).repeat(shp[0], axis=0)) # Recover original shape; scale if necessary rastr_normalized = rastr_normalized.reshape(shp) if scale is not None: rastr_normalized = np.multiply(rastr_normalized, scale) # Fill in the NoData areas from the original raster np.place(rastr_normalized, rastr == nodata, nodata) return rastr_normalized
def as_mask(path, nodata=-9999): ''' Converts all non-zero values in all bands to ones. ''' rast, gt, wkt = as_array(path) # Create a baseline raster base = np.empty((1, rast.shape[-2], rast.shape[-1])) base.fill(False) # Case of multiband raster if rast.ndim == 3: # Update the mask for nonzero values in any band for i in range(rast.shape[0]): np.logical_or(base, (rast[i,...].ravel() > 0).reshape(rast[i,...].shape), out=base) # Repeat the value of one (1) across the bands np.place(rast, base.repeat(rast.shape[0], axis=0), (1,)) elif rast.ndim == 2: # Create a single band (dim-3 array) rast = rast.reshape((1, rast.shape[-2], rast.shape[-1])) # Update the mask for nonzero values in any band np.logical_or(base, (rast.ravel() > 0).reshape(rast.shape), out=base) # Repeat the value of one (1) across the bands np.place(rast, base, (1,)) else: raise ValueError('Number of array dimensions must be 2 or 3') # Replace the NoData values rast[rast == nodata] = 0 return (rast, gt, wkt)
def substitute_values(self, vect): """ Internal method to substitute integers into the vector, and construct metadata to convert back to the original vector. np.nan is always given -1, all other objects are given integers in order of apperence. Parameters ---------- vect : np.array the vector in which to substitute values in """ try: unique = np.unique(vect) except: unique = set(vect) unique = [ x for x in unique if not isinstance(x, float) or not isnan(x) ] arr = np.copy(vect) for new_id, value in enumerate(unique): np.place(arr, arr==value, new_id) self.metadata[new_id] = value arr = arr.astype(np.float) np.place(arr, np.isnan(arr), -1) self.arr = arr if -1 in arr: self.metadata[-1] = self._missing_id
def extract(condition, arr): """ Return the elements of an array that satisfy some condition. This is equivalent to ``np.compress(ravel(condition), ravel(arr))``. If `condition` is boolean ``np.extract`` is equivalent to ``arr[condition]``. Note that `place` does the exact opposite of `extract`. Parameters ---------- condition : array_like An array whose nonzero or True entries indicate the elements of `arr` to extract. arr : array_like Input array of the same size as `condition`. Returns ------- extract : ndarray Rank 1 array of values from `arr` where `condition` is True. See Also -------- take, put, copyto, compress, place Examples -------- >>> arr = np.arange(12).reshape((3, 4)) >>> arr array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> condition = np.mod(arr, 3)==0 >>> condition array([[ True, False, False, True], [False, False, True, False], [False, True, False, False]], dtype=bool) >>> np.extract(condition, arr) array([0, 3, 6, 9]) If `condition` is boolean: >>> arr[condition] array([0, 3, 6, 9]) """ return _nx.take(ravel(arr), nonzero(ravel(condition))[0])
def append(arr, values, axis=None): """ Append values to the end of an array. Parameters ---------- arr : array_like Values are appended to a copy of this array. values : array_like These values are appended to a copy of `arr`. It must be of the correct shape (the same shape as `arr`, excluding `axis`). If `axis` is not specified, `values` can be any shape and will be flattened before use. axis : int, optional The axis along which `values` are appended. If `axis` is not given, both `arr` and `values` are flattened before use. Returns ------- append : ndarray A copy of `arr` with `values` appended to `axis`. Note that `append` does not occur in-place: a new array is allocated and filled. If `axis` is None, `out` is a flattened array. See Also -------- insert : Insert elements into an array. delete : Delete elements from an array. Examples -------- >>> np.append([1, 2, 3], [[4, 5, 6], [7, 8, 9]]) array([1, 2, 3, 4, 5, 6, 7, 8, 9]) When `axis` is specified, `values` must have the correct shape. >>> np.append([[1, 2, 3], [4, 5, 6]], [[7, 8, 9]], axis=0) array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> np.append([[1, 2, 3], [4, 5, 6]], [7, 8, 9], axis=0) Traceback (most recent call last): ... ValueError: arrays must have same number of dimensions """ arr = asanyarray(arr) if axis is None: if arr.ndim != 1: arr = arr.ravel() values = ravel(values) axis = arr.ndim-1 return concatenate((arr, values), axis=axis)
def signed_distance_transform(pmap, pmin, minMembraneSize, out_debug_image_dict, ppitch = None): """ Performs a threshold on the given image 'pmap' > pmin, and performs a distance transform to the threshold region border for all pixels outside the threshold boundaries (positive distances) and also all pixels *inside* the boundary (negative distances). The result is a signed float32 image. """ # get the thresholded pmap binary_membranes = (pmap >= pmin).view(numpy.uint8) # delete small CCs labeled = vigra.analysis.labelMultiArrayWithBackground(binary_membranes) save_debug_image('thresholded membranes', labeled, out_debug_image_dict) del binary_membranes remove_wrongly_sized_connected_components(labeled, minMembraneSize, in_place=True) save_debug_image('filtered membranes', labeled, out_debug_image_dict) # perform signed dt on mask logger.debug("positive distance transform...") if ppitch != None: distance_to_membrane = vigra.filters.distanceTransform(labeled, pixel_pitch = ppitch) else: distance_to_membrane = vigra.filters.distanceTransform(labeled) # Save RAM with a sneaky trick: # Use distanceTransform in-place, despite the fact that the input and output don't have the same types! # (We can just cast labeled as a float32, since uint32 and float32 are the same size.) logger.debug("negative distance transform...") distance_to_nonmembrane = labeled.view(numpy.float32) if ppitch != None: vigra.filters.distanceTransform(labeled, background=False, out=distance_to_nonmembrane, pixel_pitch = ppitch) else: vigra.filters.distanceTransform(labeled, background=False, out=distance_to_nonmembrane, pixel_pitch = ppitch) del labeled # Delete this name, not the array # Combine the inner/outer distance transforms distance_to_nonmembrane[distance_to_nonmembrane>0] -= 1 distance_to_membrane[:] -= distance_to_nonmembrane save_debug_image('distance transform', distance_to_membrane, out_debug_image_dict) return distance_to_membrane
def binary_mask(rast, mask, nodata=-9999, invert=False): ''' Applies an arbitrary, binary mask (data in [0,1]) where pixels with a value of 1 are pixels to be masked out. Arguments: rast A gdal.Dataset or a NumPy array mask A gdal.Dataset or a NumPy array nodata The NoData value; defaults to -9999. invert Invert the mask? (tranpose meaning of 0 and 1); defaults to False. ''' # Can accept either a gdal.Dataset or numpy.array instance if not isinstance(rast, np.ndarray): rastr = rast.ReadAsArray() else: rastr = rast.copy() if not isinstance(mask, np.ndarray): maskr = mask.ReadAsArray() else: maskr = mask.copy() if not np.alltrue(np.equal(rastr.shape[-2:], maskr.shape[-2:])): raise ValueError('Raster and mask do not have the same shape') # Convert Boolean arrays to ones and zeros if maskr.dtype == bool: maskr = maskr.astype(np.int0) # Transform into a "1-band" array and apply the mask if maskr.shape != rastr.shape: maskr = maskr.reshape((1, maskr.shape[-2], maskr.shape[-1]))\ .repeat(rastr.shape[0], axis=0) # Copy the mask across the "bands" # TODO Compare to place(), e.g., # np.place(rastr, mask.repeat(rastr.shape[0], axis=0), (nodata,)) # Mask out areas that match the mask (==1) if invert: rastr[maskr < 1] = nodata else: rastr[maskr > 0] = nodata return rastr