【问题标题】:Split dataframe by column values Scala按列值Scala拆分数据框
【发布时间】:2020-12-14 02:12:32
【问题描述】:

我需要通过时间戳列将一个数据帧拆分为多个数据帧。所以我会提供这个数据框应该包含的小时数,并将获得一组数据框,每个数据框都有指定的小时数。

方法的签名如下所示:

def splitDataframes(df: DataFrame, hoursNumber: Int): Seq[DataFrame]

我怎样才能做到这一点?

数据框的架构如下所示:

root
 |-- date_time: integer (nullable = true)
 |-- user_id: long (nullable = true)
 |-- order_id: string (nullable = true)
 |-- description: string (nullable = true)
 |-- event_date: date (nullable = true)
 |-- event_ts: timestamp (nullable = true)
 |-- event_hour: long (nullable = true)

一些输入df字段:

event_ts, user_id
2020-12-13 08:22:00, 1
2020-12-13 08:51:00, 2
2020-12-13 09:28:00, 1
2020-12-13 10:53:00, 3
2020-12-13 11:05:00, 1
2020-12-13 12:19:00, 2

hourNumber=2 的一些输出 df 字段:

df1   event_ts, user_id
      2020-12-13 08:22:00, 1
      2020-12-13 08:51:00, 2
      2020-12-13 09:28:00, 1
df2   2020-12-13 10:46:00, 3
      2020-12-13 11:05:00, 1
df3   2020-12-13 12:48:00, 2

【问题讨论】:

  • 为什么 2020-12-13 12:19:00 在单独的数据框中?距离 2020-12-13 10:53:00 不到 2 小时
  • 嗯,我是从 2020-12-13 10:00:00 这样的偶数小时开始计算的,因此这个时间不属于这个数据帧。我将更新该值,以免造成混淆
  • 我已经按照你的方式编辑了我的答案,看看它是否适合你?

标签: scala apache-spark apache-spark-sql


【解决方案1】:

将时间戳转换为unix时间戳,然后使用与最早时间戳的时间差计算出每一行的id。

编辑:如果您从 00:00:00 开始计算开始时间,则解决方案会更简单。

import org.apache.spark.sql.DataFrame

def splitDataframes(df: DataFrame, hoursNumber: Int): Seq[DataFrame] = {

    val df2 = df.withColumn(
        "event_unix_ts",
        unix_timestamp($"event_ts")
    ).withColumn(
        "grouping",
        floor($"event_unix_ts" / (3600 * hoursNumber))
    ).drop("event_unix_ts")
    
    val df_array = df2.select("grouping").distinct().collect().map(
                   x => df2.filter($"grouping" === x(0)).drop("grouping")).toSeq
    
    return df_array

}

【讨论】:

  • 谢谢。我已经测试了几个小时的步骤太小了,我实际上需要一批需要 4-10 天。如何将此解决方案配置为在一批中花费几天而不简单地乘以小时数?有一个日期列可用于此
  • @Cassie 使用 86400 而不是 3600。一天有 86400 秒。
  • 听起来像是一个选择,谢谢你的想法。可以将相同的底数算法应用于日期还是按小时运行更好?
  • @Cassie 我认为可以,因为在这段代码中输入被转换为 unix 时间戳,所以大概它应该适用于日期或时间戳
  • @Cassie 我现在明白你的意思了,那么是的,应该可以实现它,但是如果你不介意你可以用样本数据、期望的输出等打开另一个问题吗?这与您在此问题中所要求的非常不同。
猜你喜欢
  • 2020-10-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-05
  • 2021-09-01
  • 2016-06-27
  • 1970-01-01
  • 2022-01-26
  • 2019-11-12
相关资源
最近更新 更多