大資料處理-Bitmap
MapReduce是一種程式設計模型,用於大規模資料集(大於1TB)的並行運算。概念"Map(對映)"和"Reduce(歸約)"
Bit-map空間壓縮和快速排序去重
1. Bit-map的基本思想
32位機器上,對於一個整型數,比如int a=1 在記憶體中佔32bit位,這是為了方便計算機的運算。但是對於某些應用場景而言,這屬於一種巨大的浪費,因為我們可以用對應的32bit位對應儲存十進位制的0-31個數,而這就是Bit-map的基本思想。Bit-map演算法利用這種思想處理大量資料的排序、查詢以及去重。
Bitmap在使用者群做交集和並集運算的時候也有極大的便利。
2. Bit-map應用之快速排序
假設我們要對0-7內的5個元素(4,7,2,5,3)排序(這裡假設這些元素沒有重複),我們就可以採用Bit-map的方法來達到排序的目的。要表示8個數,我們就只需要8個Bit(1Bytes),首先我們開闢1Byte的空間,將這些空間的所有Bit位都置為0,
對應位設定為1:
遍歷一遍Bit區域,將該位是一的位的編號輸出(2,3,4,5,7),這樣就達到了排序的目的,時間複雜度O(n)。
優點:
運算效率高,不需要進行比較和移位;
佔用記憶體少,比如N=10000000;只需佔用記憶體為N/8=1250000Byte=1.25M。
缺點:
所有的資料不能重複。即不可對重複的資料進行排序和查詢。
3. Bit-map應用之快速去重
2.5億個整數中找出不重複的整數的個數,記憶體空間不足以容納這2.5億個整數。
首先,根據“記憶體空間不足以容納這2.5億個整數”我們可以快速的聯想到Bit-map。下邊關鍵的問題就是怎麼設計我們的Bit-map來表示這2.5億個數字的狀態了。其實這個問題很簡單,一個數字的狀態只有三種,分別為不存在,只有一個,有重複。因此,我們只需要2bits就可以對一個數字的狀態進行儲存了,假設我們設定一個數字不存在為00,存在一次01,存在兩次及其以上為11。那我們大概需要儲存空間幾十兆左右。
接下來的任務就是遍歷一次這2.5億個數字,如果對應的狀態位為00,則將其變為01;如果對應的狀態位為01,則將其變為11;如果為11,,對應的轉態位保持不變。
最後,我們將狀態位為01的進行統計,就得到了不重複的數字個數,時間複雜度為O(n)。
4. Bit-map應用之快速查詢
同樣,我們利用Bit-map也可以進行快速查詢,這種情況下對於一個數字只需要一個bit位就可以了,0表示不存在,1表示存在。假設上述的題目改為,如何快速判斷一個數字是夠存在於上述的2.5億個數字集合中。
同之前一樣,首先我們先對所有的數字進行一次遍歷,然後將相應的轉態位改為1。遍歷完以後就是查詢,由於我們的Bit-map採取的是連續儲存(整型陣列形式,一個數組元素對應32bits),我們實際上是採用了一種分桶的思想。一個數組元素可以儲存32個狀態位,那將待查詢的數字除以32,定位到對應的陣列元素(桶),然後再求餘(%32),就可以定位到相應的狀態位。如果為1,則代表改數字存在;否則,該數字不存在。
5. Bit-map擴充套件——Bloom Filter(布隆過濾器)
當一個元素被加入集合中時,通過k各雜湊函式將這個元素對映成一個位數組中的k個點,並將這k個點全部置為1.
有一定的誤判率--在判斷一個元素是否屬於某個集合時,有可能會把不屬於這個集合的元素誤判為屬於這個集合.因此,它不適合那些"零誤判"的應用場合.在能容忍低誤判的應用場景下,布隆過濾器通過極少的誤判換區了儲存空間的極大節省.
Bloom Filter使用k個相互獨立的雜湊函式(Hash Function),它們分別將集合中的每個元素對映到{1,…,m}的範圍中。對任意一個元素x,第i個雜湊函式對映的位置hi(x)就會被置為1(1≤i≤k)。注:如果一個位置多次被置為1,那麼只有第一次會起作用,後面幾次將沒有任何效果。
在判斷y是否屬於這個集合時,對y應用k次雜湊函式,若所有hi(y)的位置都是1(1≤i≤k),就認為y是集合中的元素,否則就認為y不是集合中的元素。
6. 總結
使用Bit-map的思想,我們可以將儲存空間進行壓縮,而且可以對數字進行快速排序、去重和查詢的操作。Bloom Fliter是Bit-map思想的一種擴充套件,它可以在允許低錯誤率的場景下,大大地進行空間壓縮,是一種拿錯誤率換取空間的資料結構。
7. 應用
適用範圍:可進行資料的快速查詢,判重,刪除,一般來說資料範圍是int的10倍以下
基本原理及要點:使用bit陣列來表示某些元素是否存在,比如8位電話號碼
擴充套件:bloom filter可以看做是對bit-map的擴充套件
問題例項:
1、已知某個檔案內包含一些電話號碼,每個號碼為8位數字,統計不同號碼的個數。
8位最多99 999 999,大概需要99m個bit,大概10幾M位元組的記憶體即可。
2、在2.5億個整數中找出不重複的整數,記憶體不足以容納這2.5億個整數。
方案1:採用2-Bitmap(每個數分配2bit,00表示不存在,01表示出現一次,10表示多次,11無意義)進行,共需記憶體232*2bit=1GB記憶體,還可以接受。然後掃描這2.5億個整數,檢視Bitmap中相對應位,如果是00變01,01變10,10保持不變。所描完事後,檢視bitmap,把對應位是01的整數輸出即可。