当前位置: 首页 > 知识库问答 >
问题:

如何有效地仅选择包含给定行子集值变化的列?

燕烨
2023-03-14

对于上下文,我的最终目标是从非常大的数据帧中删除几乎重复的行。以下是一些虚拟数据:

+---+--------+----------+---+-------+-------+---+-------+-------+
|key|unique_1|  unique_2|...|col_125|col_126|...|col_414|col_415|
+---+--------+----------+---+-------+-------+---+-------+-------+
|  1|     123|01-01-2000|...|      1|   true|...|    100|     25|
|  2|     123|01-01-2000|...|      0|  false|...|    100|     25|
|  3|     321|12-12-2012|...|      3|   true|...|     99|      1|
|  4|     321|12-12-2012|...|      3|  false|...|     99|      5|
+---+--------+----------+---+-------+-------+---+-------+-------+

在此数据中,来自unique_1和unique_2的观测值的组合应该是不同的,但它们并非总是如此。当它们重复时,它们对于绝大多数列具有相同的值,但在非常小的其他列集上具有变化。我正在尝试制定一种策略来处理近似重复项,但这很复杂,因为每组近似重复项都有一组不同的列,其中包含变化。

我正在尝试一次查看包含一组近似重复项的变体的列 - 如下所示:

+---+-------+-------+
|key|col_125|col_126|
+---+-------+-------+
|  1|      1|   true|
|  2|     20|  false|
+---+-------+-------+

或者这个:

+---+-------+-------+
|key|col_126|col_415|
+---+-------+-------+
|  3|   true|      1|
|  4|  false|      5|
+---+-------+-------+

我用几种不同的方法成功地得到了这个结果。这是我的第一次尝试:

def findColumnsWithDiffs(df: DataFrame): DataFrame = {

    df.columns.foldLeft(df){(a,b) =>
        a.select(b).distinct.count match {
            case 1 => a.drop(b)
            case _ => a
        }
    }
}

val smallFrame = originalData.filter(($"key" === 1) || ($"key" === 2))
val desiredOutput = findColumnsWithDiffs(smallFrame)

这是我想要的,但速度太慢了。上面的函数运行的速度大约比在smallFrame中显示所有数据的速度慢10倍(我认为性能只会随着数据的大小而变差-尽管我没有彻底测试这个假设)。

我认为使用的折叠而不是的折叠可能会产生一些改进,所以我像这样重写了find委员函数:

def findColumnsWithDiffsV2(df: DataFrame): DataFrame = {

    val colsWithDiffs = df.columns.map(colName => List(colName)).toList.fold(Nil){(a,b) =>
        df.select(col(b(0))).distinct.count match {
            case 1 => a
            case _ => a ++ b
        }
    }

    df.select(colsWithDiffs.map(colName => col(colName)):_*)

}

但表现是一样的。我还尝试将每一列映射到它具有的不同值的数量,并从中工作,但性能还是一样的。现在我没有主意了。我的直觉是,每一列都在进行过滤,这就是为什么过滤速度如此之慢的原因,但我不知道如何验证这一理论和/或改变我正在做的事情,如果我是正确的话。有没有人有提高我工作效率的想法?

我目前使用的是spark 2.1.0 / scala 2.11.8

共有1个答案

陶成济
2023-03-14

识别不同值的所有方法都很好,问题在于过滤器的惰性评估。若要提高性能,请在使用< code>findColsWithDiffs之前调用< code>smallFrame.cache。这将把过滤后的数据保存在内存中,这很好,因为一次只有几行。

 类似资料:
  • 问题内容: 如果我有一张桌子 如何通过task_id获取分组的行,该行的状态仅为NULL。在这种情况下,只有具有task_id 2的行。 问题答案: 执行,以返回仅具有空状态的task_id。

  • 考虑一个案例类: 和一个 包含该类的许多实例。 唯一键是元组。然而,我们确实有一些副本。 是否有任何有效的方法来删除重复项? 手术 将查找重复的整行。 回退将涉及将唯一的组合连接回整个行:我正在研究如何做到这一点。但即便如此,还是有几次手术。更简单的方法(也更快?)如果它存在的话会很有用。

  • 我正在编写一个查询来选择所有行,其中所有子行只包含相同的值,而不包含其他场景。 尝试了很多网上的例子,没有匹配。 从所有子级仅包含相同值而没有其他方案的表中选择*。必须包含至少一个要返回的子级。 子级通过ID映射到父级。 子值为一列,可以为int或null。假设所有子级必须包含值5,而不包含任何其他值。如果大多数子级都包含5,则将不起作用,则必须是所有子级都只有5的家长。 父级可能有多个子级 父级

  • 我对SQL并不陌生,但我对Hibernate完全陌生。我预计,给定一个列值,从表中选择一组对象将是一项非常简单的任务。但我做不到。 我的导师和下面的这个问题都建议了同样的事情,这让我写了下面的代码: JPA:如何基于除ID之外的字段值获取实体? 这是可行的,但方法是已被弃用。由于我对hibernate还不熟悉,我不妨按照它的预期工作方式来学习它,所以我不想使用不推荐的方法。 官方的Hibernat

  • 问题内容: 我想选择不具有VAL =’current’的任何行的唯一ID(与多行关联)。 例如,在这样的表中: 我希望它返回ID 23,因为它没有VAL =’current’的行。请注意,在此表中,主键(PK)是唯一的,但ID不是唯一的(因此需要使用DISTINCT或GROUP BY)。 这是我在PHP中拥有的东西: 这就是它的总要旨。如您所见,完成此任务需要两个SQL语句。有没有更短的方法可以做

  • 问题内容: 我需要一个棘手的hibernate查询问题的帮助。我有以下实体: 和 两者之间存在多对多关联,这由联接表books_tags_mn和book_id和tag_id列表示。 我喜欢做的事情是:我要创建一个Hibernate查询/标准查询,返回所有的书,有 所有的 一组特定的标签。什么工作是选择具有所有书籍 的任何 一组的标签。 我一直在使用标准API,但并没有真正理解它。所以我想做的事(使