在pyspark中创建一个大字典

时间:2014-07-01 14:58:14

标签: python apache-spark

我正在尝试使用pyspark解决以下问题。 我在hdfs上有一个文件,格式是查找表的转储。

key1, value1
key2, value2
...

我想将它加载到pyspark中的python字典中,并将其用于其他目的。所以我试着这样做:

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

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

我发现表变量没有被修改。那么,有没有办法在spark中创建一个大型内存哈希表?

2 个答案:

答案 0 :(得分: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")访问,该{{1}}返回与该键相关联的一系列值,但这肯定不会像其他分布式KV商店那样高效,因为火花并非真正为此构建。

答案 1 :(得分: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和高效地完成这个技巧。