2014-07-01 107 views
9

我想用pyspark解決以下問題。 我有一個hdfs格式的文件,它是查找表的轉儲。在pyspark中創建一個大字典

key1, value1 
key2, value2 
... 

我想加載到python字典中的pyspark並將其用於其他目的。所以我試圖做到:

table = {} 
def populateDict(line): 
    (k,v) = line.split(",", 1) 
    table[k] = v 

kvfile = sc.textFile("pathtofile") 
kvfile.foreach(populateDict) 

我發現表變量沒有被修改。那麼,有沒有辦法在spark中創建一個大的內存哈希表?

回答

4

foreach是一個分佈式計算,所以你不能指望它修改只在驅動程序中可見的數據結構。你想要的是。

kv.map(line => { line.split(" ") match { 
    case Array(k,v) => (k,v) 
    case _ => ("","") 
}.collectAsMap() 

這是Scala,但你的想法,最重要的功能是collectAsMap()返回地圖給司機。

如果您的數據非常大,您可以使用PairRDD作爲地圖。第一地圖中對

kv.map(line => { line.split(" ") match { 
     case Array(k,v) => (k,v) 
     case _ => ("","") 
    } 

那麼你就可以rdd.lookup("key")返回與該鍵關聯的值的順序訪問,雖然這肯定不會像其他分佈式KV存儲一樣高效,火花是不是真的爲建那。

+0

很感謝。這是否意味着地圖必須適合驅動程序的內存?還是它仍然分佈? – Kamal

+0

@Kamal是啊它必須適應內存。 U可以使用pair rdd作爲查找表。也想到一個可積累的解決方案,將很快發佈 – aaronman

+0

好吧。我正在尋找火花中的分佈式地圖。看起來不可能! – Kamal

1

爲了提高效率,請參見:sortByKey() and lookup()

查找(鍵):

返回值的列表中RDD的關鍵鑰匙。如果RDD具有已知的分區程序,則只需搜索該鍵映射到的分區即可高效地執行此操作。

的RDD將由sortByKey()(see: OrderedRDD)重新分配,並且在lookup()呼叫高效地搜索。在代碼中,類似的,

kvfile = sc.textFile("pathtofile") 
sorted_kv = kvfile.flatMap(lambda x: x.split("," , 1)).sortByKey() 

sorted_kv.lookup('key1').take(10) 

將作爲一個RDD和有效的伎倆。