Reputation: 5292
I am new in scientific computing.
I have a 2D numpy array(say, A) with shape as (11153L, 4218L)
, datatype is dtype('uint8')
.Now, I want to keep data at some(say, 10000) random positions (row,col) and fill the rest with no-data-value
- How can I do this?
Here no-data-value
is got from another environmental variable e.g.my_raster_nodata_values = dsc.noDataValue
Upvotes: 0
Views: 68
Reputation: 221534
You could use np.random.choice
with the optional arg replace
set as False
to select unique indices for the total size of that array and set those in it as no_data_value
. Thus, an implementation would be -
a.ravel()[np.random.choice(a.size,a.size-10000,replace=0)] = no_data_value
Alternatively, we can use np.put
as to make it more intuitive, like so -
np.put(a, np.random.choice(a.size,a.size-10000,replace=0), no_data_value)
A sample run should make it easier to understand -
In [94]: a # Input array
Out[94]:
array([[163, 80, 142, 169, 214],
[ 7, 59, 102, 104, 234],
[ 44, 143, 7, 30, 232],
[ 71, 15, 64, 42, 141]])
In [95]: no_data_value = 0 # No value specifier
In [98]: N = 10 # Number of elems to keep
In [99]: a.ravel()[np.random.choice(a.size,a.size-N,replace=0)] = no_data_value
In [100]: a
Out[100]:
array([[ 0, 0, 142, 0, 0],
[ 7, 0, 0, 104, 234],
[ 0, 0, 7, 30, 232],
[ 71, 0, 64, 0, 141]])
If you already have one or more elements in the input array that are equal to no_data_value
, we might want to offset the number of elements to be set based on that count. So, for such a case, we would have a modified version, like so -
S = a.size - N - (a == no_data_value).sum()
idx = np.random.choice(np.flatnonzero(a!=no_data_value),S,replace=0)
a.ravel()[idx] = no_data_value
Sample run -
In [65]: a
Out[65]:
array([[240, 30, 61, 38, 145],
[ 91, 65, 108, 154, 118],
[155, 198, 65, 65, 189],
[248, 140, 154, 186, 186]])
In [66]: no_data_value = 65 # No value specifier
In [67]: N = 10 # Number of elems to keep
In [68]: S = a.size - N - (a == no_data_value).sum()
In [69]: idx = np.random.choice(np.flatnonzero(a!=no_data_value),S,replace=0)
In [70]: a.ravel()[idx] = no_data_value
In [71]: a
Out[71]:
array([[240, 30, 61, 38, 65],
[ 65, 65, 108, 65, 65],
[ 65, 198, 65, 65, 65],
[248, 140, 154, 186, 65]])
Upvotes: 2