【问题标题】:Joining multiple data frames in one statement and selecting only required columns在一个语句中连接多个数据框并仅选择所需的列
【发布时间】:2018-12-05 18:47:01
【问题描述】:

我有以下 Spark DataFrame:

  • df1 与列 (id, name, age)
  • df2 与列 (id, salary, city)
  • df3 与列 (name, dob)

我想使用 Python 连接所有这些 Spark 数据帧。这是我需要复制的 SQL 语句。

SQL:

select df1.*,df2.salary,df3.dob
from df1    
left join df2 on df1.id=df2.id    
left join df3 on df1.name=df3.name

我使用 python 在 Pyspark 中尝试了如下所示的操作,但收到错误消息。

joined_df = df1.join(df2,df1.id=df2.id,'left')\
               .join(df3,df1.name=df3.name)\
               .select(df1.(*),df2(name),df3(dob)

我的问题:我们可以一次性加入所有三个 DataFrame 并选择所需的列吗?

【问题讨论】:

  • 我需要python而不是scala的答案
  • df1.(*) 语法无效。

标签: python pyspark pyspark-sql


【解决方案1】:

您可以利用colalias 使类似SQL 的语法正常工作。确保您的 DataFrame 具有别名:

df1 = df1.alias('df1')
df2 = df2.alias('df2')
df3 = df3.alias('df3')

那么以下应该可以工作:

from pyspark.sql.functions import col

joined_df = df1.join(df2, col('df1.id') == col('df2.id'), 'left') \
.join(df3, col('df1.name') == col('df3.name'), 'left') \
.select('df1.*', 'df2.salary', 'df3.dob')

【讨论】:

  • @pault 感谢您指出这一点。我已经相应地更新了我的回复。
  • 我认为您在这里甚至不需要 df2df3 的别名。我还没有测试,但我认为以下应该可以工作:joined_df = df1.alias('df1').join(df2, on='id', how='left').join(df3, on='name', how='left').select('df1.*', 'salary', 'dob')
  • @pault 谢谢你。我学到了一些新东西 - 下次有机会一定会尝试一下。
  • @pault 感谢您的回答,它就像魅力一样,但是我想知道我们是否可以分组和汇总字段并一次只选择必填字段,您可以使用相同的示例并按名称分组, age 并获取 max(dob) 并一次只选择列 name,age,maxdob
  • @bobby1985 StackOverflow 上有很多帖子展示了如何做到这一点。搜索窗口函数或聚合函数。如果这些不能解决您的问题,请提出一个新问题。
【解决方案2】:

如果您有一个有效的 SQL 查询,为什么不使用pyspark-sql

首先使用pyspark.sql.DataDrame.createOrReplaceTempView()将你的DataFrame注册为临时表:

df1.createOrReplaceTempView('df1')
df2.createOrReplaceTempView('df2')
df3.createOrReplaceTempView('df3')

现在您可以使用您在createOrReplaceTempView() 的参数中提供的名称以表格的形式访问这些 DataFrame。使用pyspark.sql.SparkSession.sql() 执行您的查询:

query = "select df1.*, df2.salary, df3.dob " \
        "from df1 " \
        "left join df2 on df1.id=df2.id "\
        "left join df3 on df1.name=df3.name"

joined_df = spark.sql(query)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-29
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 2011-12-13
    • 1970-01-01
    • 2018-09-05
    相关资源
    最近更新 更多