我注意到spark的功能collect
在处理大量数据时非常慢,因此我试图使用并行化来解决此问题。
我的main方法创建了spark会话,并将其传递给get_data
函数。
def main():
spark = SparkSession.builder.appName('app_name').getOrCreate()
return get_data(spark)
在这里我尝试并行化收集功能
def get_data(spark):
df = all_data(spark)
data = spark.sparkContext.parallelize(df.select('my_column').distinct().collect())
return map(lambda row: row['my_column'], data)
这不起作用,并返回此错误:
TypeError:“ RDD”对象不可迭代
有人对get_data
函数如何并行化或提高性能有任何想法。
答案 0 :(得分:2)
以下是使用broadcast
变量的 static 和 dynamic 方法的示例(每个执行程序存储器中均保留有只读变量;避免传输复制驱动程序上的列表以获取每个分布式任务),以检索列的不同值。另外,如果您在pivot
期间未提供硬编码的值,则会触发额外作业(广泛的转换顺序)以获取该列的不同值。
免责声明=>对于动态方法,在性能方面可能会有更好的选择
print(spark.version)
2.4.3
import pyspark.sql.functions as F
# sample data
rawData = [(1, "a"),
(1, "b"),
(1, "c"),
(2, "a"),
(2, "b"),
(2, "c"),
(3, "a"),
(3, "b"),
(3, "c")]
df = spark.createDataFrame(rawData).toDF("id","value")
# static list example
l = ["a", "b", "c"]
l = spark.sparkContext.broadcast(l)
pivot_static_df = df\
.groupby("id")\
.pivot("value", l.value)\
.agg(F.expr("first(value)"))
pivot_static_df.show()
+---+---+---+---+
| id| a| b| c|
+---+---+---+---+
| 1| a| b| c|
| 3| a| b| c|
| 2| a| b| c|
+---+---+---+---+
# dynamic list example
v = df.select("value").distinct().rdd.flatMap(lambda x: x).collect()
v = spark.sparkContext.broadcast(v)
print(v.value)
pivot_dynamic_df = df\
.groupby("id")\
.pivot("value", l.value)\
.agg(F.expr("first(value)"))
pivot_dynamic_df.show()
['c', 'b', 'a']
+---+---+---+---+
| id| a| b| c|
+---+---+---+---+
| 1| a| b| c|
| 3| a| b| c|
| 2| a| b| c|
+---+---+---+---+