至少有三種選擇:
- 你確定它必須是從全套? 10%的樣本應該是一個非常非常好的近似值。
- 300k個元素不是那麼大的一個向量,但是一個300k x 100 +列矩陣很大。將需要的列拖到內存中,而不是整個矩陣(如果需要,可以在每列中重複)。
- 按順序進行,可能與一個較小的樣本結合起來,讓您開始在正確的場地。對於第五百分位數,您只需知道當前猜測上方有多少物品,以及下方有多少物品。所以像這樣:
- 採取1%的樣本,找到它的第5個百分點。在上下跳動一些容差,以確保第5個百分點位於該範圍內。
- 以塊爲單位讀取矩陣。對於每個塊,計數在範圍之上和範圍之下的觀測值的數量。然後保留在該範圍內的所有觀察值。
- 當你讀完最後一個塊時,你現在有三條信息(上面的計數,下面的計數,內部的觀察向量)。採取分位數的一種方法是對整個向量進行排序並找到第n個觀察值,並且可以用上述信息做到這一點:對範圍內的觀察值進行排序,並找到(n-count_below)th。
編輯:實施例(3)。
請注意,我不是一個冠軍算法設計師,有人幾乎可以肯定爲此設計了一個更好的算法。而且,這個實現並不是特別有效。如果速度對您來說很重要,請考慮Rcpp,或者爲此更加優化R。製作一堆列表然後從中提取數值並不是那麼聰明,但是這樣做很容易,所以我就使用它。
library(plyr)
set.seed(1)
# -- Configuration -- #
desiredQuantile <- .25
# -- Generate sample data -- #
# Use some algorithm (sampling, iteration, or something else to come up with a range you're sure the true value lies within)
guessedrange <- c(.2, .3)
# Group the observations to correspond to the OP's files
dat <- data.frame(group = rep(seq(100), each=100), value = runif(10000))
# -- Apply the algorithm -- #
# Count the number above/below and return the values within the range, by group
res <- dlply(dat, .(group), function(x, guessedrange) {
above <- x$value > guessedrange[2]
below <- x$value < guessedrange[1]
list(
aboveCount = sum(above),
belowCount = sum(below),
withinValues = x$value[ !above & !below ]
)
}, guessedrange = guessedrange)
# Exract the count of values below and the values within the range
belowCount <- sum(sapply(res, function(x) x$belowCount))
belowCount
withinValues <- do.call(c, sapply(res, function(x) x$withinValues))
str(withinValues)
# Count up until we find the within value we want
desiredQuantileCount <- floor(desiredQuantile * nrow(dat)) #! Should fix this so it averages when there's a tie
sort(withinValues)[ desiredQuantileCount - belowCount + 1 ]
# Compare to exact value
quantile(dat$value, desiredQuantile)
最後,這個值與確切的版本有些偏差。我懷疑我被一個或一些同樣愚蠢的解釋轉移了過來,但也許我錯過了一些基本的東西。
感謝您的回答! 1.我需要全套設置,因爲每個文件都是不同模型的結果,不同的模型會返回非常不同的結果。 2.每一列代表一個時間步驟,因此我需要所有列。 3.如果我理解的很好,這種方法會返回很好的近似值,但不是確切的值,對嗎? – Claudia
(3)應該是確切的。但(1)的要點是你可以抽樣。因此,加載每個文件,抽樣1或5%的行,加載下一個文件。隨機化的樂趣意味着你得到的答案會非常接近確切的版本。 –
在(3)中必須有不同的範圍(特別是因爲模型不同),所以你不能簡單地將所有收集的範圍數據排序在一起:它們不對齊。必須檢測所有範圍的交集(每個給出一個子範圍),然後在那裏進行排序可以完成,但是分位數計算仍然不是那麼直接,因爲每個子範圍都有不同的「移位」(它們是來自不同的概率間隔!)。如果你考慮所有*和*範圍內的抽樣不確定性,那麼算法應該可以正常工作。 – Quartz