加入数据集并重命名一列
Joining datasets and renaming one column
我知道如何完成它,但我想(或者至少我希望)有一种更简单、更少样板的方法来完成同样的事情。
场景:
Employee
+-------+---+------------+
| NAME|AGE|COMPANY_CODE|
+-------+---+------------+
| John| 41| 1|
| Mary| 34| 1|
| Chris| 32| 2|
|Phillip| 22| 2|
| Tony| 44| 1|
+-------+---+------------+
Company
+----+---------+
|CODE| NAME|
+----+---------+
| 1|Company-1|
| 2|Company-2|
| 3|Company-3|
+----+---------+
我的目标是通过 employee.company_code 和 company_code 连接两个表,并显示 employee.name 作为 NAME,employee.age 作为 AGE,company.name 作为 COMPANY_NAME(这是技巧部分)
// company columns
final Column companyCode = companyDataSet.col("CODE");
// employee columns
final Column employeeCompanyCode = employeeDataSet.col("COMPANY_CODE");
Dataset<Row> join = employeeDataSet.join(companyDataSet, employeeCompanyCode.equalTo(companyCode));
join = join.drop(companyCode).drop(employeeCompanyCode);
打印加入数据帧,现在我们得到:
+-------+---+---------+
| NAME|AGE| NAME|
+-------+---+---------+
| John| 41|Company-1|
| Mary| 34|Company-1|
| Chris| 32|Company-2|
|Phillip| 22|Company-2|
| Tony| 44|Company-1|
+-------+---+---------+
我不能使用 withColumnRenamed 方法 (join.withColumnRenamed("NAME", "COMPANY_NAME") 因为我有两个名为 NAME 的列,并且两者都将重命名
我发现这样做的唯一方法是定义我想要显示的所有列,将它们全部传递给 select 数据集方法,然后根据需要重命名列:
final Column companyName = companyDataSet.col("NAME");
final Column employeeName = employeeDataSet.col("NAME");
final Column employeeAge = employeeDataSet.col("AGE");
join = join.select(employeeName, employeeAge, companyName.alias("COMPANY_NAME"));
+-------+---+------------+
| NAME|AGE|COMPANY_NAME|
+-------+---+------------+
| John| 41| Company-1|
| Mary| 34| Company-1|
| Chris| 32| Company-2|
|Phillip| 22| Company-2|
| Tony| 44| Company-1|
+-------+---+------------+
在这种特定情况下,定义我想要 select 的所有列并不是什么大问题,因为它们只是几列,但想象一下在包含大量列的表中。因为一个悲惨的列重命名而定义很多列太痛苦了。
知道如何避免这种情况吗?
你应该可以做到:
join = join.withColumnRenamed(companyDataSet.col("NAME"), "COMPANY_NAME")
这会解决您的问题吗?
一种方法是将它们注册为临时表并写一个 SQL?
employee.createOrReplaceTempView(emp)
company.createOrReplaceTempView(comp)
spark.sql("select t1.Name as Name, t1.Age as Age, t2.Name as Company_Name
from
emp t1 join comp t2
on
t1.id = t2.id")
我找到了一个简单的解决方案,不像我认为的那样优雅 dataset.withColumnRenamed 接受列作为第一个参数,但它比仅因为一个列重命名而包含所有列要好。
在加入 employeeDataSet 之前,只需重命名 companyDataSet 中的列 NAME:
companyDataSet = companyDataSet.withColumnRenamed("NAME", "COMPANY_NAME");
我知道如何完成它,但我想(或者至少我希望)有一种更简单、更少样板的方法来完成同样的事情。
场景:
Employee
+-------+---+------------+
| NAME|AGE|COMPANY_CODE|
+-------+---+------------+
| John| 41| 1|
| Mary| 34| 1|
| Chris| 32| 2|
|Phillip| 22| 2|
| Tony| 44| 1|
+-------+---+------------+
Company
+----+---------+
|CODE| NAME|
+----+---------+
| 1|Company-1|
| 2|Company-2|
| 3|Company-3|
+----+---------+
我的目标是通过 employee.company_code 和 company_code 连接两个表,并显示 employee.name 作为 NAME,employee.age 作为 AGE,company.name 作为 COMPANY_NAME(这是技巧部分)
// company columns
final Column companyCode = companyDataSet.col("CODE");
// employee columns
final Column employeeCompanyCode = employeeDataSet.col("COMPANY_CODE");
Dataset<Row> join = employeeDataSet.join(companyDataSet, employeeCompanyCode.equalTo(companyCode));
join = join.drop(companyCode).drop(employeeCompanyCode);
打印加入数据帧,现在我们得到:
+-------+---+---------+
| NAME|AGE| NAME|
+-------+---+---------+
| John| 41|Company-1|
| Mary| 34|Company-1|
| Chris| 32|Company-2|
|Phillip| 22|Company-2|
| Tony| 44|Company-1|
+-------+---+---------+
我不能使用 withColumnRenamed 方法 (join.withColumnRenamed("NAME", "COMPANY_NAME") 因为我有两个名为 NAME 的列,并且两者都将重命名
我发现这样做的唯一方法是定义我想要显示的所有列,将它们全部传递给 select 数据集方法,然后根据需要重命名列:
final Column companyName = companyDataSet.col("NAME");
final Column employeeName = employeeDataSet.col("NAME");
final Column employeeAge = employeeDataSet.col("AGE");
join = join.select(employeeName, employeeAge, companyName.alias("COMPANY_NAME"));
+-------+---+------------+
| NAME|AGE|COMPANY_NAME|
+-------+---+------------+
| John| 41| Company-1|
| Mary| 34| Company-1|
| Chris| 32| Company-2|
|Phillip| 22| Company-2|
| Tony| 44| Company-1|
+-------+---+------------+
在这种特定情况下,定义我想要 select 的所有列并不是什么大问题,因为它们只是几列,但想象一下在包含大量列的表中。因为一个悲惨的列重命名而定义很多列太痛苦了。
知道如何避免这种情况吗?
你应该可以做到:
join = join.withColumnRenamed(companyDataSet.col("NAME"), "COMPANY_NAME")
这会解决您的问题吗?
一种方法是将它们注册为临时表并写一个 SQL?
employee.createOrReplaceTempView(emp)
company.createOrReplaceTempView(comp)
spark.sql("select t1.Name as Name, t1.Age as Age, t2.Name as Company_Name
from
emp t1 join comp t2
on
t1.id = t2.id")
我找到了一个简单的解决方案,不像我认为的那样优雅 dataset.withColumnRenamed 接受列作为第一个参数,但它比仅因为一个列重命名而包含所有列要好。
在加入 employeeDataSet 之前,只需重命名 companyDataSet 中的列 NAME:
companyDataSet = companyDataSet.withColumnRenamed("NAME", "COMPANY_NAME");