apache-spark - spark如何在几列上合并两个数据框?
问题描述
我有两个数据框
- a 列:['q1', 'q2', 'q3', 'a1', 'a2']
- b 列:['q1', 'q2', 'q3', 'b', 'b2']
a 可能有一些 ['q1', 'q2', 'q3'] 不在 b 中,b 也可能有一些 ['q1', 'q2', 'q3'] 不在 a 中。
合并意味着,如果 a 有 ['q1', 'q2', 'q3'] 与 b 相同,则加入 rows ,然后联合 left rows 。full outer join
不做这样的事情。
我的 presudo 代码是这样的:
c = a.join(b, on= ['q1', 'q2', 'q3'], how='inner')
c = c.union(a.filter( ~a.withColumn('xxx', F.concat_ws('|', 'q1', 'q2', 'q3') ).isin(c.select(F.concat_ws('|', 'q1', 'q2', 'q3')) )
c = c.union(b.filter( ~b.withColumn('xxx', F.concat_ws('|', 'q1', 'q2', 'q3') ).isin(c.select(F.concat_ws('|', 'q1', 'q2', 'q3')) )
但这是非常低效的。
有没有更好的办法?
解决方案
我忘了解决这个问题。
其实full outer join
是正确的方法。但是 spark 中有一个相关的错误,在 2.1 版本中标记为已解决,但我在 2.4.0 中遇到了。
在完全外部联接之前进行内部联接时的意外结果:
df1 = spark.parquet.read(...)
df2 = spark.parquet.read(...)
df3 = spark.parquet.read(...)
df4 = spark.parquet.read(...)
df5 = spark.parquet.read(...)
store_product = spark.parquet.read(...)
df1 = df1.join(store_product, on=['store_id', 'product_id'], how='inner')
dfs = [df1,df2,df3,df4,df5,]
df = full_outer_join_all(dfs)
将内部联接移到完全外部正确的后面:
df1 = spark.parquet.read(...)
df2 = spark.parquet.read(...)
df3 = spark.parquet.read(...)
df4 = spark.parquet.read(...)
df5 = spark.parquet.read(...)
store_product = spark.parquet.read(...)
dfs = [df1,df2,df3,df4,df5,]
df = full_outer_join_all(dfs)
df = df.join(store_product, on=['store_id', 'product_id'], how='inner')
PS:并非所有数据集都发生这种情况,我创建了一些数据进行测试但无法重现。
推荐阅读
- conda - 将要求添加到“运行”或“主机”失败 conda-build
- docker - docker 容器同时关闭,重新启动失败,错误为将 max 写入 pids.max,我该如何找到问题?
- node.js - 在 nodejs 中,如何在事务中使用 async/await 而不是通过“then”来解析承诺?
- django - 在单个谷歌云应用引擎实例上部署 DjangoREST+React 项目。可能吗?
- javascript - 将图像上传到 Firebase 时 Nativescript ProgressBar 未更新(仅在 100% 后更新)
- http - 通过 HTTP 请求关注 Azure acklog 项
- python - Pandas:如果某列连续出现少于 n 次,则将 True 设置为 False
- android - 设置 shell 脚本 Android SELinux 策略以在系统启动时启动它已完成
- javascript - 优化 javascript/jquery 代码以在弹出窗口中加载表单
- create-react-app - 覆盖 CRA 基本 linting 规则