在map()或任何其他解决方案中使用sc.parallelize?

时间:2016-10-19 01:20:26

标签: apache-spark pyspark apache-spark-sql graphframes

我遇到以下问题:我需要在A列中找到每个ID的B列中所有值的组合,并将结果作为DataFrame返回

在输入DataFrame下面的示例中

        A     B       
0       5    10       
1       1    20      
2       1    15       
3       3    50       
4       5    14       
5       1    30       
6       1    15       
7       3    33       

我需要获取以下输出DataFrame(适用于GraphX \ GraphFrame)

        src dist      A
0       10   14       5
1       50   33       3
2       20   15       1
3       30   15       1
4       20   30       1

我想到的一个解决方案是:

df_result = df.drop_duplicates().\
               map(lambda (A,B):(A,[B])).\
               reduceByKey(lambda p, q: p + q).\
               map(lambda (A,B_values_array):(A,[k for k in itertools.combinations(B_values_array,2)]))

print df_result.take(3)

输出:[(1,[(20,15),(30,20),(30,15)]),(5,[(10,14)]),(3,[(50,33) )])]

在这里,我被卡住了:(如何将其返回到我需要的数据框架?一个想法是使用并行化:

import spark_sc

edges = df_result.map(lambda (A,B_pairs): spark_sc.sc.parallelize([(k[0],k[1],A) for k in B_pairs]))

对于spark_sc我有其他文件名为spark_sc.py

def init():
    global sc
    global sqlContext

    sc = SparkContext(conf=conf,
                  appName="blablabla",
                  pyFiles=['my_file_with_code.py'])

    sqlContext = SQLContext(sc)

但我的代码失败了:

AttributeError: 'module' object has no attribute 'sc'

如果我使用spark_sc.sc()而不是map()则可以使用。

知道我在最后一步中想念的是什么吗?是否可以使用parallelize()?或者我需要完全不同的解决方案 谢谢!

1 个答案:

答案 0 :(得分:1)

你肯定需要另一种解决方案,它可以简单:

from pyspark.sql.functions import greatest, least, col

df.alias("x").join(df.alias("y"), ["A"]).select(
    least("x.B", "y.B").alias("src"), greatest("x.B", "y.B").alias("dst"), "A"
).where(col("src") != col("dst")).distinct()

其中:

df.alias("x").join(df.alias("y"), ["A"])

通过A

连接表格
least("x.B", "y.B").alias("src")

greatest("x.B", "y.B")

选择值较低的id作为来源,将较高的ID作为目的地。最后:

where(col("src") != col("dst"))

放弃自我循环。

一般情况下,无法在动作或转换中使用SparkContext(并非在您的情况下执行此操作会有任何意义)。