1

比較的高次元 (100X500000) の行列 Q があり、それをダウンサンプリングしたいと考えています。ダウンサンプルで、例を挙げて説明します。

Q =

1 4 9
3 2 1

ダウンサンプル サイズ = n。sum(Q) = 20 個のボールの瓶から n 個のボールを描画したいと考えています。各ボールは、行列の異なるインデックス ペアに対応する 6 つの方法のうちの 1 つに色付けされています。Aの色のボールが1つ、Bの色のボールが4つ、というように、n個のボールを置き換えずに描いているようなものです。

マトリックスと同じ形式で返してほしい。戻り値の一例。たとえば、downsample(Q, 3) =

0 0 2
1 0 0

私のアプローチは、サンプルを使用しようとしています:

sample(length(as.vector(Q)), size=n, replace=FALSE, prob = as.vector(Q))

ただし、これの問題は、サンプルが 1:length(as.vector(Q)) を私が持っているすべてのボールと見なすため、長さ(as.vector(Q)) 以外のボールを描画できないことです。私のボールを交換します。

したがって、私の方法を適応させるには、このベクトルから 1 を減算して prob を更新し、何らかの for ループを使用してサンプルを 1 つずつ呼び出す必要があります。素敵なコードのようには聞こえません。

R に適した for ループの方法でこれを行うより良い方法はありますか?

4

2 に答える 2

6

少し非効率的ですが、大きすぎsum(Q)ない場合は、ベクトルを分解/複製してからサンプリングし、再集約/集計することでこれを行うことができます。

Q <- setNames(c(1,4,9,3,2,1),LETTERS[1:6])
n <- 10
set.seed(101)
s0 <- sample(rep(names(Q),Q),
       size=n,replace=FALSE)
Q2 <- table(factor(s0,levels=names(Q)))
## A B C D E F 
## 1 2 5 1 0 1 

あなたのマトリックス構造についてはわかりません。dim(Q2) <- dim(Q)元のマトリックスと同じ順序で結果を再編成するために使用できます...

于 2016-11-18T21:26:44.197 に答える
3

これがかなり良い方法の1つです。最初の TRUE 値which(x <= cq)[1]を見つけるために特別に作成された関数に置き換えることで、(必要に応じて) 効率を向上させることができます。

Q = matrix(c(1, 4, 9, 3, 2, 1), nrow = 2)

set.seed(47)
samp = sample(sum(Q), size = 3)
cq = cumsum(Q)

inds = table(sapply(samp, function(x) which(x <= cq)[1]))

result = integer(length(Q))
result[as.integer(names(inds))] = inds
dim(result) = dim(Q)
#      [,1] [,2] [,3]
# [1,]    0    2    0
# [2,]    0    0    1
于 2016-11-18T21:38:50.983 に答える