Java Spark中数据帧的正确连接?
我是火花框架的新手,需要一些帮助 假设第一个数据帧(Java Spark中数据帧的正确连接?,java,scala,apache-spark,Java,Scala,Apache Spark,我是火花框架的新手,需要一些帮助 假设第一个数据帧(df1)存储用户访问呼叫中心的时间 +---------+-------------------+ |USER_NAME| REQUEST_DATE| +---------+-------------------+ | Mark|2018-02-20 00:00:00| | Alex|2018-03-01 00:00:00| | Bob|2018-03-01 00:00:00| | Mark|201
df1
)存储用户访问呼叫中心的时间
+---------+-------------------+
|USER_NAME| REQUEST_DATE|
+---------+-------------------+
| Mark|2018-02-20 00:00:00|
| Alex|2018-03-01 00:00:00|
| Bob|2018-03-01 00:00:00|
| Mark|2018-07-01 00:00:00|
| Kate|2018-07-01 00:00:00|
+---------+-------------------+
第二个数据框存储关于某人是否是组织成员的信息OUT
表示用户已离开组织<代码>在中表示用户已来到组织<代码>开始日期和结束日期
表示相应流程的开始和结束
例如,您可以看到,Alex
在2018-01-01 00:00:00
离开了组织,而此过程在2018-02-01 00:00:00
结束。您可以注意到,一个用户可以在不同的时间进出组织,如Mark
+---------+---------------------+---------------------+--------+
|NAME | START_DATE | END_DATE | STATUS |
+---------+---------------------+---------------------+--------+
| Alex| 2018-01-01 00:00:00 | 2018-02-01 00:00:00 | OUT |
| Bob| 2018-02-01 00:00:00 | 2018-02-05 00:00:00 | IN |
| Mark| 2018-02-01 00:00:00 | 2018-03-01 00:00:00 | IN |
| Mark| 2018-05-01 00:00:00 | 2018-08-01 00:00:00 | OUT |
| Meggy| 2018-02-01 00:00:00 | 2018-02-01 00:00:00 | OUT |
+----------+--------------------+---------------------+--------+
我试图在决赛中得到这样一个数据帧。它必须包含来自第一个数据帧的所有记录,并加上一列,指示该人员在请求时是否为组织成员(request\u DATE
)
代码:
val df1: DataFrame = Seq(
("Mark", "2018-02-20 00:00:00"),
("Alex", "2018-03-01 00:00:00"),
("Bob", "2018-03-01 00:00:00"),
("Mark", "2018-07-01 00:00:00"),
("Kate", "2018-07-01 00:00:00")
).toDF("USER_NAME", "REQUEST_DATE")
df1.show()
val df2: DataFrame = Seq(
("Alex", "2018-01-01 00:00:00", "2018-02-01 00:00:00", "OUT"),
("Bob", "2018-02-01 00:00:00", "2018-02-05 00:00:00", "IN"),
("Mark", "2018-02-01 00:00:00", "2018-03-01 00:00:00", "IN"),
("Mark", "2018-05-01 00:00:00", "2018-08-01 00:00:00", "OUT"),
("Meggy", "2018-02-01 00:00:00", "2018-02-01 00:00:00", "OUT")
).toDF("NAME", "START_DATE", "END_DATE", "STATUS")
df2.show()
其收益率为:
到目前为止,您尝试了什么?你在某一点上绊倒了吗?如果不提供完整的答案就很难回答这样的问题,因为答案没有多大用处。您好!:)现在我正试图用您的逻辑测试代码。在我想要的最终结果中,记录数必须与第一个数据帧中的记录数相同。我对第二步感到困惑。当我按用户分组时,这意味着计数会更少,对吗?你能展示一下第二步的代码吗?嘿,你还对它感兴趣吗?我现在有更多的时间,我可以解决它。你好!:)我需要帮助。如果你能帮助我,我将非常感激。你好!谢谢你的回答。对不起,回答得太长了。直到现在我才能够检查你的代码。不幸的是,我在编写
lastRowByRequestId
的代码时遇到困难。在IDEA中,我看到语法错误。例如,这里的groupByKey(u.REQUEST\u ID)
IDEA say me无法解析符号请求\u ID
。顺便问一下,为什么要使用数据集
?在post中,您可以看到我使用了DataFrame
。我的代码将2DataFrame
作为输入并输出一个DataFrame
。我使用数据集的原因:1。它们非常棒,因为它们增强了数据帧:它们是类型安全的。2.我在代码中使用的reducegroup
来自数据集API,使我的代码成为可能,如果没有它,那将是非常痛苦的。关于您的IDE问题:我100%保证我的代码正常工作,所以如果您没有完全运行我的代码,请尝试复制粘贴它完全是我的代码。否则,请确保您使用的是Spark 2+
val df1: DataFrame = Seq(
("Mark", "2018-02-20 00:00:00"),
("Alex", "2018-03-01 00:00:00"),
("Bob", "2018-03-01 00:00:00"),
("Mark", "2018-07-01 00:00:00"),
("Kate", "2018-07-01 00:00:00")
).toDF("USER_NAME", "REQUEST_DATE")
df1.show()
val df2: DataFrame = Seq(
("Alex", "2018-01-01 00:00:00", "2018-02-01 00:00:00", "OUT"),
("Bob", "2018-02-01 00:00:00", "2018-02-05 00:00:00", "IN"),
("Mark", "2018-02-01 00:00:00", "2018-03-01 00:00:00", "IN"),
("Mark", "2018-05-01 00:00:00", "2018-08-01 00:00:00", "OUT"),
("Meggy", "2018-02-01 00:00:00", "2018-02-01 00:00:00", "OUT")
).toDF("NAME", "START_DATE", "END_DATE", "STATUS")
df2.show()
import org.apache.spark.sql.Dataset
import org.apache.spark.sql.functions._
case class UserAndRequest(
USER_NAME:String,
REQUEST_DATE:java.sql.Date,
START_DATE:java.sql.Date,
END_DATE:java.sql.Date,
STATUS:String,
REQUEST_ID:Long
)
val joined : Dataset[UserAndRequest] = df1.withColumn("REQUEST_ID", monotonically_increasing_id).
join(df2,$"USER_NAME" === $"NAME", "left").
as[UserAndRequest]
val lastRowByRequestId = joined.
groupByKey(_.REQUEST_ID).
reduceGroups( (x,y) =>
if (x.REQUEST_DATE.getTime > x.END_DATE.getTime && x.END_DATE.getTime > y.END_DATE.getTime) x else y
).map(_._2)
def logic(status: String): String = {
if (status == "IN") "Our user"
else if (status == "OUT") "not our user"
else "No Information"
}
val logicUDF = udf(logic _)
val finalDF = lastRowByRequestId.withColumn("USER_STATUS",logicUDF($"REQUEST_DATE"))