在python中使用BitMap排序
學習過redis快取穿透解決方案的可能知道布隆過濾器,關於布隆過濾器的知識這裡不再多講,它的底層使用的是bitmap實現的,bitmap就是一個二進位制的bit位組成的陣列,一個int型別為4個位元組,則bit位為32位(1Byte=8bit),減去一個符號位,我們可用的位數為31位,也就可以用bit位對應的1來表示對應的十進位制整數。
使用bitmap對整數陣列排序時首先我們要分配這個bitmap的大小,獲取陣列中的最大整數 M,M//31+1 除以31向上取整,比如一個未排序陣列最大數不超過60,那麼得到結果為2,意思是我們需要兩個int型資料大小的空間來存放這個陣列。
bm=[a[0],a[1]] ,a[0]和a[1]就是我們申請到的資源,a[0]的0-31位分別表示整數的0-31,a[1]的0-31位分別表示整數的32-63,排序時只需將陣列中元素對應bit位的0置為1即表示該整數存在,一趟下來每個陣列中的元素都在對應的bit位被置為1.我們輸出排序結果時只需按順序輸出為1的bit位的索引即可。比如a=[1,5,3,4,7,8,15,6,9] 我們只需用16位的bit即可表示全部整數,他們在bitmap中的位置應該是這樣的“1000001111111010” 從左往右數為1的位置索引就是1,3,4,5,6,7,8,9,15這就是a的排序結果。
上面的方法是不是太複雜了,python中有沒有更簡便的方法呢?
一切從簡,pip install bitmap ,我們只需下載第三方包bitmap。這個包直接為我們封裝了一系列的bitmap用法,比自己寫容易多了。
import bitmap
print(dir(bitmap))
#result:['BitMap', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'bitmap']
[Finished in 0.3s]
首先引引入bitmap模組,使用dir檢視有哪些屬性,BitMap這個應該就是類,我們可以使用它來建立一個bitmap物件。
from bitmap import BitMap
a=[1,5,3,4,7,8,15,6,9]
bm=BitMap(max(a))
print(dir(bm))
print(bm.tostring())
for i in a:
bm.set(i)
print(bm.tostring())
print(bm.nonzero())
#
['BITMASK', 'BIT_CNT', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'all', 'any', 'bitmap', 'count', 'flip', 'fromhexstring', 'fromstring', 'none', 'nonzero', 'reset', 'set', 'size', 'test', 'tohexstring', 'tostring']
0000000000000000
1000001111111010
[1, 3, 4, 5, 6, 7, 8, 9, 15]
我們先引入bitmap包下的BitMap類,例項化一個bm物件,BitMap初始化時傳入的引數值為我們需要排序的陣列中的最大值,他可以幫我們自動分配所需的最小位數。bm此時應該是16位的0,使用dir(bm),可以發現它有三個方法set、tostring和nonzero字面意思理解為轉為字串,非零位,我們使用set(陣列中的元素值),將a中的元素全部存入bm的bit位置為1,使用bm.tostring()方法可以看到每一個為1的位對應的索引就是a中的元素的值。只需輸出這個為1的索引列表即為我們的排序結果。nonzero方法就是封裝好的方法。
bitmap排序有什麼用呢?
該演算法為解決大量的資料排序而生,如一個10G的檔案,每行都為數字,想要對它進行排序,我們要考慮記憶體不夠的情況,如果使用bitmap排序則可以大大減少空間資源使用。
缺點有哪些?
- bitmap的缺點如果我們需要排序的元素數量過少且間隔過大,就容易造成空間浪費,比如一個陣列只有[1,100000]兩個元素,使用bitmap就很浪費空間。
- bitmap無法保留陣列中的重複元素,因為每個位置只能儲存一個資料,若兩個相同的資料都在a中,經過bitmap排序後的輸出只會有一個,這也可以算作它的優勢幫我們自動去重。
以上僅為個人理解,有不對的地方也請賜教。關於bitmap的更多用法後續有用到再做探討。
相關文章
- Redis 中 BitMap 的使用場景Redis
- getopt在Python中的使用Python
- input在python中的使用注意Python
- reload在python中的使用Python
- JSON在Python中的使用JSONPython
- sqlalchemy在python中的使用(基本使用)一SQLPython
- 【Google官方教程】第四課:在UI中顯示BitmapGoUI
- Android Bitmap 使用Android
- PHP實現bitmap點陣圖排序求交集PHP排序
- 在ListCtrl中進行排序 (轉)排序
- Android中的BitmapAndroid
- Redis 中 Bitmap 詳解Redis
- 探索Bitmap使用姿勢
- Bitmap的分析與使用
- 核心中bitmap的使用
- C中qsort快速排序使用排序
- 「Python實用祕技07」在pandas中實現自然順序排序Python排序
- Python中幾種lambda排序方法Python排序
- AES演算法在Python中的使用演算法Python
- 使用 Beautiful Soup 在 Python 中抓取網頁Python網頁
- 在Spring Data Elasticsearch 4中使用地理距離排序 - sothawoSpringElasticsearch排序
- 在狀態列中加入BitMap (轉)
- Mock 在 Python 單元測試中的使用MockPython
- 深入理解python中的排序sortPython排序
- 使用 Redis bitmap 在微擎內做公眾號的簽到活動Redis
- 在Java中對集合當中的物件進行排序Java物件排序
- Oracle中B-Tree、Bitmap和函式索引使用案例總結Oracle函式索引
- 使用 singledispatch 在 Python 中追溯地新增方法Python
- sqlalchemy在python中的使用(關於查詢)二SQLPython
- Python爬蟲之路-chrome在爬蟲中的使用Python爬蟲Chrome
- Python中按字母順序對列表排序Python排序
- 物化檢視上使用bitmap索引索引
- python技巧 使用值來排序一個字典Python排序
- android中Bitmap的剪下與拉伸Android
- 在python中如何分句Python
- Python爬蟲之路-selenium在爬蟲中的使用Python爬蟲
- 如何在Python中對dicts列表進行排序Python排序
- ☕【難點攻克技術系列】「海量資料計算系列」如何使用BitMap在海量資料中對相應的進行去重、查詢和排序排序