Dataframe PySpark通过另一个数据帧中的转换创建新列

Dataframe PySpark通过另一个数据帧中的转换创建新列,dataframe,design-patterns,pyspark,functional-programming,apache-spark-sql,Dataframe,Design Patterns,Pyspark,Functional Programming,Apache Spark Sql,在PySpark中寻找功能更强大、计算效率更高的方法-> 我有一个主表(包含数十亿行),感兴趣的列有: id-(字符串) 令牌-(数组(字符串))-ex、['alpha','beta','gamma'] --(称之为数据帧,df1) 我还有另一个汇总表,其中包含前25个令牌,如: --(称之为数据帧,df2) 例: 代币 阿尔法 贝塔 梓 亩 现在,对于第二个表(或dataframe),我希望添加一行,其中包含第一个表中该标记的ID列表,因此结果如下所示: 令牌ID α[1,2,3] 贝塔[3,

在PySpark中寻找功能更强大、计算效率更高的方法->

我有一个主表(包含数十亿行),感兴趣的列有:

id-(字符串)

令牌-(数组(字符串))-ex、['alpha','beta','gamma']

--(称之为数据帧,df1)

我还有另一个汇总表,其中包含前25个令牌,如:

--(称之为数据帧,df2) 例:

代币 阿尔法

贝塔

现在,对于第二个表(或dataframe),我希望添加一行,其中包含第一个表中该标记的ID列表,因此结果如下所示:

令牌ID α[1,2,3]

贝塔[3,5,6,8,9]

子[2,8,12]

Mu[1,15,16,17]

当前方法:

从df2中,找出不同的标记并将其存储为列表(比如l1)


我同意这是一种terribe方法,对于任何具有100k记录的l1,它将永远运行。有谁能帮我重写代码(Pyspark)

分解
df1
tokens
数组列,然后
使用
df2
连接
(左连接),使用小写的tokens和token,然后
groupBy
标记,并按设置收集
id

from pyspark.sql import functions as f
#exolode tokens column for joining with df2
df1 = df1.withColumn('tokens', f.explode('tokens'))

#left join with case insensitive and collecting ids as set for each token
df2.join(df1, f.lower(df1.tokens) == f.lower(df2.token), 'left')\
    .groupBy('token')\
    .agg(f.collect_set('id').alias('ids'))\
    .show(truncate=False)

我希望答案是有帮助的

您也可以尝试在一个新列上连接这两个表,该列基本上只包含分解到各个行的标记。这对计算效率、分配的资源和所需的处理时间都有帮助


此外,还有一些机箱内加入特权,包括“地图端加入”,这将进一步推动您的事业

我可以在这里利用的其他连接优势如何?请尝试在配置单元配置中进行以下更改:将hive.optimize.bucketmappjoin设置为true。请尝试在配置单元配置中进行以下更改:将hive.optimize.bucketmappjoin.sortedmerge设置为true。请尝试在配置单元中进行以下更改:将hive.input.format设置为org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat。
from pyspark.sql import functions as f
#exolode tokens column for joining with df2
df1 = df1.withColumn('tokens', f.explode('tokens'))

#left join with case insensitive and collecting ids as set for each token
df2.join(df1, f.lower(df1.tokens) == f.lower(df2.token), 'left')\
    .groupBy('token')\
    .agg(f.collect_set('id').alias('ids'))\
    .show(truncate=False)