大資料中位數怎麼運算 計算大資料的中位數

2021-10-13 12:17:30 字數 1094 閱讀 8865

題目:在乙個大檔案中有10g個整數,亂序排列,要求找出中位數(記憶體有2g限制,不能一次全部加裝),請寫出演算法設計思路。

中位數的定義:對於乙個排序好的序列,如果資料有奇數個的話,中位數就取中間的乙個;如果有偶數個的話,中位數一般取中間兩個數的平均值。

解題:思路一:堆排序(轉換為求前5g大的元素)

堆排序的常用場景之一是選擇topk元素,這種做法不需要對資料進行排序,只需要拿新資料與堆頂資料進行比較即可,它也不需要一次性將全部資料都載入到記憶體,只需要構建乙個k個大小的堆。當我們需要求前k小的資料時,構建乙個大頂堆,當讀取的新資料比堆頂元素大時捨棄,比堆頂元素小時,替換掉堆頂元素並進行堆化,重複這一過程直至讀取完全部資料,最後堆中的資料就是前k小的資料。當我們需要求前k大的資料時,構建乙個小頂堆,當讀取的新資料比堆頂元素小時捨棄,比堆頂元素大時,替換掉堆頂元素並進行堆化,重複這一過程直至讀取完全部資料,最後堆中的資料就是前k大的資料。

對於10g的資料,它的中位數就是第5g個元素,但是記憶體只有2g,無法構建大小為5g的堆。因此,我們先遍歷資料,構建乙個1g大小的大頂堆,得到堆頂元素,即第1g大小的元素,然後利用該元素構建乙個新的1g大小的堆,求出第2g大的元素,依次類推直至求出第5g大的元素。

這種方法需要多次遍歷全部資料,頻繁的磁碟io操作降低了效率。

1.假設整數為有符號的32位資料,其取值範圍是[-2^31, 2^31-1],將範圍等份劃分10000段,即thread_1,thread_2...thread_10000。

2.將資料分為10組依次讀入。首先裝載第乙個1g個數,遍歷這些數,看它們落入thread_1至thread_10000的哪個區間,落入的對應區間統計計數增1;然後裝載第二個1億個數,重複比較與計數。

3.資料全部裝載一次之後,從thread_1的計數開始累加,直至計數累加到全部資料的一半(假設為n/2),那麼第n/2個元素所在的區間thread_i就包含了中位數。

4.假設中位數區間的範圍是[a, b],且前面所有區間的資料計數共有m個,再次按照每組1g個元素遍歷全部資料,對於處在thread_i區間的每個元素都進行計數。

5.當thread_i區間每個元素的計數累加之和加上m第一次超過n/2時,該計數處的元素就是中位數。

這種方法需要兩次遍歷全部資料,效率較高。

大資料處理 求中位數

中位數並不是大小位於中間的數,而是排序之後,位置位於中間的數。若是n個數,n為奇數,則中位數是陣列a 排序之後 a n 1 2 若n為偶數,中位數是 a n 2 a n 2 1 2 如 5 5 5 6 7 8 9 中位數是6 題目 只有2g記憶體的pc機,在乙個存有10g個整數的檔案,從中找到中位數...

大資料運算

1 大數的資料型別設計 可以用乙個string和乙個long long型別來表示乙個大數型別,long long型別表示沒有超出範圍,string表示超出範圍的大數。在初始化的時候我們可以將string和long long都進行初始化,在運算的時候再判斷是用long long運算還是用string進...

java大資料運算

大數運算類似的文章有很多,本文主要分享一下自己的經驗。把實現思路寫一下,希望能夠幫助到有需要的人。關於整數的運算通常有byte short int long,當時數字有20位或者更長的時候,原有的資料型別已經不能使用,所以需要大數的運算,實現如下 實現大數的運算 通過byte陣列運算,實現了進製的靈...