到目前为止我所拥有的是:
lookup = sc.textFile("/user/myuser/lookup.asv")
lookup.map(lambda r: r.split(chr(1)) )
现在我的RDD看起来像
[
[filename1, category1],
[filename2, category2],
...
[filenamen, categoryn]
]
如何将该RDD转换为广播词典,如:
{filename1: category1, filename2: category2, ...}
这是我尝试但不工作的原因:
>>> broadcastVar = sc.broadcast({})
>>> data = sc.parallelize([[1,1], [2,2], [3,3], [4,4]])
>>> def myfunc(x):
... broadcastVar[str(x[0])] = x[1]
...
>>> result = data.map(myfunc)
>>> broadcastVar
<pyspark.broadcast.Broadcast object at 0x7f776555e710>
>>> broadcastVar.value
{}
>>> result.collect()
...
ERROR: TypeError: 'Broadcast' object does not support item assignment
...
>>> broadcastVar.value
{}
有关我为什么要构建这个巨大的查找变量的更多信息,请阅读:
这是one的后续问题。
我有两张表
table1:一个非常宽的(25K列和150K行)表,其中每列包含像素信息,第一列是输入图像文件的文件名。
table2:TSV(制表符分隔文件)文件,有300万行,每行包含图像文件名和图像的产品类别。
在SQL中,我需要对文件名上的这两个表进行内部联接,这样我就可以标记图像数据,以便以后在机器学习上使用。
在任何类型的SQL中执行它是不现实的,因为你必须为table1创建一个具有25K列的表,create table语法将是荒谬的。
然后我考虑使用table2创建一个查找变量,并可能使它成为一个广播变量,其中键是文件名,值是产品类别。
答案 0 :(得分:0)
广播变量对工人是只读的。 Spark提供只写的累加器,但这些累积器用于计数器之类的东西。在这里,您可以简单地收集和创建Python字典:
<script type="text/javascript" src="Scripts/jasmine.js"></script>
<script type="text/javascript" src="Scripts/jasmine-html.js"></script>
<script type="text/javascript" src="Scripts/boot.js"></script>
<script type="text/javascript" src="Scripts/require.js"></script>
<script type="text/javascript">
require.config({
paths: {
"jquery": './Scripts/jquery-1.10.2.min',
"knockout": './Scripts/knockout.debug',
"testViewModel" :"./Scripts/viewmodel",
}
});
// list spec files here
require(["knockout","jquery","specs/someSpec", "testViewModel"], function () {
window.onload();
});
</script>
在任何类型的SQL中执行它是不现实的,因为你必须为table1创建一个具有25K列的表,create table语法将是荒谬的。
创造应该不是问题。只要您知道名称,就可以通过编程方式轻松创建表格:
lookup_bd = sc.broadcast({
k: v for (k, v) in lookup.map(lambda r: r.split(chr(1))).collect()
})
这里还有另一个问题,即使你使用普通的RDD也要严重得多。非常宽的行通常难以以任何行方式处理。
您可以做的一件事是使用稀疏表示,如from pyspark.sql import Row
colnames = ["x{0}".format(i) for i in range(25000)] # Replace with actual names
df = sc.parallelize([
row(*[randint(0, 100) for _ in range(25000)]) for x in range(10)
]).toDF()
## len(df.columns)
## 25000
或SparseVector
。另一种方法是使用RLE编码像素信息。