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...