m = {{0., 0., 0., 0.9}, {0., 0.05, 0., 0.}, {0., 0., 0., 0.}, {0., 0., 0.05, 0.}};
{positions, values} = {#["NonzeroPositions"], #["NonzeroValues"]} & @ SparseArray[m];
wd = WeightedData[positions, values];
RandomVariate + EmpiricalDistribution
You can use EmpiricalDistribution
+ RandomVariate
to generate a random sample of indices:
SeedRandom[777]
RandomVariate[EmpiricalDistribution[wd], 10]
{{1, 4}, {2, 2}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {4, 3}, {1, 4}, {1, 4}}
SeedRandom[1]
sampleproportions = {#, Round[#2/1000000., .01]} & @@@
Tally[RandomVariate[EmpiricalDistribution[wd], 1000000]]
{{{1, 4}, 0.9}, {{4, 3}, 0.05}, {{2, 2}, 0.05}}
which is, up to ordering, the same as
Transpose @ {positions, values}
{{{1, 4}, 0.9}, {{2, 2}, 0.05}, {{4, 3}, 0.05}}
RandomChoice + wd["EmpiricalPDF"]
Alternatively, you can use arg = values -> positions
or arg = Rule @@ Reverse @ wd["EmpiricalPDF"]
as the first argument of RandomChoice
to get a list of random indices:
SeedRandom[777]
RandomChoice[arg, 10]
{{1, 4}, {2, 2}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {4, 3}, {1, 4}, {1, 4}}
MapIndexed
SeedRandom[777]
RandomChoice[Rule @@ Transpose[Join @@ MapIndexed[{##} &, m, {2}]], 10]
{{1, 4}, {2, 2}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {4, 3}, {1, 4}, {1, 4}}
wd2 = WeightedData @@ Transpose[Join @@ MapIndexed[{#2, #} &, m, {2}]];
SeedRandom[777]
RandomVariate[EmpiricalDistribution @ wd2, 10]
{{1, 4}, {2, 2}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {4, 3}, {1, 4}, {1, 4}}