計算引擎 水塘抽樣演算法

2021-10-23 02:10:01 字數 1418 閱讀 9844

spark中的分割槽器有三種:

1.hashpartitioner分割槽可能hashpartitioner導致每個分割槽中資料量的不均勻。

2.rangepartitioner分割槽盡量保證每個分割槽中資料量的均勻,將一定範圍內的數對映到某乙個分區內。分割槽與分割槽之間資料是有序的,但分區內的元素是不能保證順序的。(這裡其實就用到了水塘抽樣演算法)

3.自定義

那水塘抽樣演算法是什麼呢?能解決什麼型別的問題呢?

問題描述:

給定乙個資料流,資料流長度n很大,且n直到處理完所有資料之前都不可知,如何在只遍歷一遍資料(o(n))的情況下,能夠隨機選取出這組資料的k個概率相等的均勻抽樣。

要求:僅掃瞄資料一次

空間複雜度為o(n),空間複雜度與整個資料量無關,只與抽樣大小有關。

掃瞄到資料的前n個資料時(n>k),儲存當前已掃瞄資料的k個均勻抽樣。

根據要求,首先體積很大記憶體一次裝不下,不能直接不能直接取n內的k個隨機數,因為n的長度是未知的。此外也不能採用不能先遍歷一遍,然後分塊儲存資料,再隨機選取。最後要求是資料選取絕對隨機的保證。

可以採用水塘抽樣演算法:

如果接受的資料量小於k,則依次放入取樣陣列中

當接收到第i個資料,i大於等於k時,在[0,i]的範圍內取乙個隨機數d 如果d落在了[0,k-1]的範圍內,則取接收到的第i個資料替換取樣陣列中下標等於d位置上的值。

重複步驟2

// @param:

input 模擬的原始陣列

// @param:k 取樣的個數

//return

:返回取樣的資料

import random

defsample

(input

, k)

: res =

for i in

range

(len

(input))

:if iinput

[i])

//先取,前k個數字放在陣列裡面

else

://如果i>k,在0和i之間,取乙個隨機數字,如果這個隨機數字小於k,就替換陣列,否則就繼續遍歷,直到結束

rand = random.randint(

0, i)

if rand < k:

res[rand]

=input

[i]return res

這種演算法的能保證概率相等的前提就是: 當資料總量加1的時候,都會在當前總量的範圍內,進行生成隨機數,這樣就能保證範圍內的所有的數字出現概率都是相等的,然後根據概率均等隨機數字來判斷,是否落在了我們取樣陣列的邊界中,如果落到了就替換原來陣列中相同的位置的值,如果沒有落到,就繼續遍歷選取,直到所有的資料處理完畢。

水塘抽樣演算法

作用 水塘抽樣演算法是一種抽樣演算法,對於乙個很大的集合,抽取的樣本值能夠保證隨機.特點 其複雜度並不很高o n 並且能夠很大程度地節省記憶體.很多大公司的面試題都考察過這個演算法,以谷歌為例,有一道關於水塘抽樣的例題 我有乙個長度為n的鍊錶,n的值非常大,我不清楚n的確切值.我怎樣能寫乙個盡可能高...

水塘抽樣(Reservoir sampling)

水塘抽樣 reservoir sampling 題目 給出乙個資料流,這個資料流的長度很大或者未知。並且對該資料流中的資料只能訪問一次。請寫出乙個隨機選擇演算法,使得資料流中所有資料被選中的概率相等。這個問題的擴充套件就是 如何從未知或者很大樣本空間隨機的取k個數?或者說,資料流長度為n行,要隨機抽...

Shuffle an Array 水塘抽樣

隨機性問題 水塘抽樣演算法可保證每個樣本被抽到的概率相等 使用場景 從包含n個專案的集合s中選取k個樣本,其中n為一很大或未知的數量,尤其適用於不能把所有n個專案都存放到主記憶體的情況 拿起第i張牌時,只從它前面的牌隨機選出j,或從它後面的牌隨機選出j交換即可 1 class solution 67...