久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Distinct Count的Bitmap怎么做排序

194次閱讀
沒有評論

共計 2699 個字符,預計需要花費 7 分鐘才能閱讀完成。

本篇內容主要講解“Distinct Count 的 Bitmap 怎么做排序”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“Distinct Count 的 Bitmap 怎么做排序”吧!

大數據(big data),IT 行業術語,是指無法在一定時間范圍內用常規軟件工具進行捕捉、管理和處理的數據集合,是需要新處理模式才能具有更強的決策力、洞察發現力和流程優化能力的海量、高增長率和多樣化的信息資產。

1. Bitmap 介紹

Bitmap 是一個十分有用的數據結構。所謂的 Bitmap 就是用一個 bit 位來標記某個元素對應的 Value,而 Key 即是該元素。由于采用了 Bit 為單位來存儲數據,因此在內存占用方面,可以大大節省。

簡而言之——用一個 bit(0 或 1)表示某元素是否出現過,其在 bitmap 的位置對應于其 index。

用 bitmap 做排序的例子:

/* Copyright (C) 1999 Lucent Technologies */
/* From  Programming Pearls  by Jon Bentley */
/* bitsort.c -- bitmap sort from Column 1
* Sort distinct integers in the range [0..N-1]
#include#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N / BITSPERWORD];
void set(int i) { a[i   SHIFT] |= (1   (i   MASK)); }
void clr(int i) { a[i   SHIFT]  = ~(1   (i   MASK)); }
int test(int i) { return a[i   SHIFT]   (1   (i   MASK)); }
int main() {
 int i;
 for (i = 0; i   N; i++)
 clr(i);
 /* Replace above 2 lines with below 3 for word-parallel init
 int top = 1 + N/BITSPERWORD;
 for (i = 0; i   top; i++)
 a[i] = 0;
 */
 while (scanf( %d ,  i) != EOF)
 set(i);
 for (i = 0; i   N; i++)
 if (test(i))
 printf(%d\n , i);
 return 0;
}

上面代碼中,用 int 的數組存儲 bitmap,對于每一個待排序的 int 數,其對應的 index 為其 int 值。

2. Distinct Count 優化

index 生成

為了使用 bitmap 做 Distinct Count,首先需得到每個用戶(uid)對應(在 bitmap 中)的 index。有兩種辦法可以得到從 1 開始編號 index 表(與 uid 一一對應):

hash,但是要找到無碰撞且 hash 值均勻分布 [1, +∞) 區間的 hash 函數是非常困難的;

維護一張 uid 與 index 之間的映射表,并增量更新

比較兩種方法,第二種方法更為簡單可行。

UV 計算

在 index 生成完成后,RDD[(uid, V)]與 RDD[(uid, index)]join 得到 index 化的 RDD。bitmap 的開源實現有 EWAH,采用 RLE(Run Length Encoding)壓縮,很好地解決了存儲空間的浪費。Distinct Count 計算轉變成了求 bitmap 中 1 的個數:

// distinct count for rdd(not pair) and the rdd must be sorted in each partition
def distinctCount(rdd: RDD[Int]): Int = { val bitmap = rdd.aggregate[EWAHCompressedBitmap](new EWAHCompressedBitmap())( (u: EWAHCompressedBitmap, v: Int) =  { u.set(v)
 u
 },
 (u1: EWAHCompressedBitmap, u2: EWAHCompressedBitmap) =  u1.or(u2)
 )
 bitmap.cardinality()
// the tuple_2 is the index
def groupCount[K: ClassTag](rdd: RDD[(K, Int)]): RDD[(K, Int)] = { val grouped: RDD[(K, EWAHCompressedBitmap)] = rdd.combineByKey[EWAHCompressedBitmap]( (v: Int) =  EWAHCompressedBitmap.bitmapOf(v),
 (c: EWAHCompressedBitmap, v: Int) =  { c.set(v)
 c
 },
 (c1: EWAHCompressedBitmap, c2: EWAHCompressedBitmap) =  c1.or(c2))
 grouped.map(t =  (t._1, t._2.cardinality()))
}

但是,在上述計算中,由于 EWAHCompressedBitmap 的 set 方法要求 int 值是升序的,也就是說 RDD 的每一個 partition 的 index 應是升序排列:

// sort pair RDD by value
def sortPairRDD[K](rdd: RDD[(K, Int)]): RDD[(K, Int)] = {
 rdd.mapPartitions(iter =  { iter.toArray.sortWith((x, y) =  x._2.compare(y._2)   0).iterator
 })
}

為了避免排序,可以為每一個 uid 生成一個 bitmap,然后在 Distinct Count 時將 bitmap 進行 or 運算亦可:

rdd.reduceByKey(_ or _)
 .mapValues(_._2.cardinality())

到此,相信大家對“Distinct Count 的 Bitmap 怎么做排序”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-16發表,共計2699字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 克山县| 易门县| 吴忠市| 冷水江市| 溆浦县| 华坪县| 绵竹市| 襄垣县| 修武县| 常山县| 淄博市| 海南省| 昌吉市| 仙游县| 太湖县| 南宁市| 霍州市| 新沂市| 灵丘县| 武强县| 剑河县| 老河口市| 石家庄市| 闻喜县| 中宁县| 五指山市| 长岛县| 梁山县| 龙海市| 奇台县| 临桂县| 开阳县| 上栗县| 阿尔山市| 阳朔县| 龙胜| 固镇县| 黄浦区| 吉首市| 文山县| 贺州市|