Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何按多列筛选数据帧?_Scala_Apache Spark_Apache Spark Sql - Fatal编程技术网

Scala 如何按多列筛选数据帧?

Scala 如何按多列筛选数据帧?,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我有一个问题如下: 我有两个数据帧 数据帧DF1: ID, Name, age 1 name1 18 2 name2 20 数据帧DF2: ID, Name, age 1 name1 18 3 name3 19 我正在尝试过滤DF2,以按ID和名称排除DF1中包含的记录,以便获得新的DF2 ID, Name, age 3 name3 19 然后合并这两个数据帧以获得最终结果: ID, Name, age 1 name1 18 2 name2 20 3

我有一个问题如下:

我有两个数据帧

数据帧DF1:

ID, Name, age
1   name1  18
2   name2  20
数据帧DF2:

ID, Name, age
1   name1 18
3   name3 19
我正在尝试过滤DF2,以按ID和名称排除DF1中包含的记录,以便获得新的DF2

ID, Name, age
3   name3  19
然后合并这两个数据帧以获得最终结果:

ID, Name, age
1   name1  18
2   name2  20
3   name3  19
要在T-SQL中实现这一点,我可以编写如下语句

插入到DF1中 从不存在的DF2中选择ID、名称、年龄 从DF1中选择1,其中DF1.ID=DF2.ID,DF1.Name=DF2.Name 但我发现sparkSQL中的dataframe不支持insert。 因此,我的问题是:

如何基于多列过滤数据帧

如何将两个数据帧合并在一起? 非常感谢您提供的任何解决方案。

联合,然后是不同的解决方案 假设记录是唯一的,实现您想要的最简单的方法是采用UNION并遵循DISTINCT:

特点:

只能访问df1一次 洗牌df1和df2,与大小无关 除非后面跟着工会 另一种方法是使用除UNION外的其他方法:

特性:

必须访问df1两次 洗牌两帧独立于大小 可用于三帧df3.unionAlldf2.exceptdf1 左外部联接,后跟选择,带有过滤器,后跟并集 最后,如果您只希望部分匹配左外部联接,则应使用过滤器后跟UNION执行以下操作:

df2.as("df2")
  .join(
    df1.select("id", "name").as("df1"),
    // join on id and name
    $"df1.id" === $"df2.id" && $"df1.name" === $"df2.name",
    "leftouter")
  // This could be replaced by .na.drop(...)
  .where($"df1.id".isNull && $"df1.Name".isNull)
  .select($"df2.id", $"df2.name", $"df2.age")
  .unionAll(df1)
  .show

// ---+-----+---+
// | ID| Name|Age|
// +---+-----+---+
// |  3|name3| 19|
// |  1|name1| 18|
// |  2|name2| 20|
// +---+-----+---+
特性:

必须访问df1两次 如果其中一个数据帧小到可以广播,则可能不需要Shufle 可与三个数据帧一起使用
看到不同的解决方案后,我想知道它们的性能。哪种解决方案在性能方面是最好的?为什么?@JacekLaskowski我自己也在考虑,其中涉及到不同的权衡。假设我们只使用两个帧,并且两个帧都很大,我会使用第一种方法,因为只有在没有分支和合并的情况下,它才能访问df1。如果有3帧涉及我们合并不同的帧,而不是我们减去,那么这是根本不适用的。如果其中一个帧足够小,可以进行广播以避免混洗,则基于连接的解决方案更可取。@JacekLaskowski老实说,我不确定,除了。看起来它不能使用广播,所以当你想和第三帧合并时,我只能用它作为第一个解决方案的替代方案。你知道如何测量它吗?我会从web UI和SparkListener开始,但也许还有更多的专业工具/方法?@JacekLaskowski UI用于简单案例,Docker+Munin用于测量对整个管道的影响通常对我来说已经足够好了。一个问题是,有很多运动部件可以单独测量这样的东西。
df1.unionAll(df2.except(df1)).show  // df2.distinct.except to drop duplicates

// +---+-----+---+
// | ID| Name|age|
// +---+-----+---+
// |  1|name1| 18|
// |  2|name2| 20|
// |  3|name3| 19|
// +---+-----+---+
df2.as("df2")
  .join(
    df1.select("id", "name").as("df1"),
    // join on id and name
    $"df1.id" === $"df2.id" && $"df1.name" === $"df2.name",
    "leftouter")
  // This could be replaced by .na.drop(...)
  .where($"df1.id".isNull && $"df1.Name".isNull)
  .select($"df2.id", $"df2.name", $"df2.age")
  .unionAll(df1)
  .show

// ---+-----+---+
// | ID| Name|Age|
// +---+-----+---+
// |  3|name3| 19|
// |  1|name1| 18|
// |  2|name2| 20|
// +---+-----+---+