使用Pyspark更新“数据框”中的分钟和秒值

问题描述 投票:0回答:1

我有如下DF:

Name    starttime               endtime
user1   2019-08-02 03:34:45   2019-08-02 03:52:03
user2   2019-08-13 13:34:10   2019-08-13 14:02:10

我想检查endtime是否在接下来的一个小时内流血,是否确实将其更新为当前小时的最后一分钟和第二秒,如下所示。

Name    starttime               endtime
user1   2019-08-02 03:34:45   2019-08-02 03:52:03
user2   2019-08-13 13:34:10   2019-08-13 13:59:59

我可以使用UDF进行如下检查和替换,但不希望使用它们。

def adjust_end_hour(date):
    return date.replace(second=59,minute=59)
adjust_end_hour_udf = udf(adjust_end_hour, TimestampType())
df = df.\
        filter(df.endtime > adjust_end_hour_udf(df.starttime)).\
withColumn('enddtime', adjust_end_hour_udf(df.starttime))

如何在不使用pyspark中使用UDF的情况下做到这一点?

谢谢

pyspark apache-spark-sql pyspark-sql
1个回答
0
投票

假设您的DataFrame具有以下架构:

df.printSchema()
#root
# |-- Name: string (nullable = true)
# |-- starttime: timestamp (nullable = true)
# |-- endtime: timestamp (nullable = true)

即其中starttimeendtime均为TimestampType()

您可以通过比较TimestampType()endtimehour部分来检查hour是否渗出到下一小时。如果它们不等于1,则意味着您需要截断结束时间。

starttime

这会告诉您哪些行需要修改。在endtime参数设置为from pyspark.sql.functions import col, hour df.withColumn( "bleeds_into_next_hour", hour(col("endtime")) != hour(col("starttime")) ).show() #+-----+-------------------+-------------------+---------------------+ #| Name| starttime| endtime|bleeds_into_next_hour| #+-----+-------------------+-------------------+---------------------+ #|user1|2019-08-02 03:34:45|2019-08-02 03:52:03| false| #|user2|2019-08-13 13:34:10|2019-08-13 14:02:10| true| #+-----+-------------------+-------------------+---------------------+ 的情况下,使用date_trunc几乎可以达到所需的输出:

date_trunc

您现在所要做的就是从format中减去1秒。最简单的方法是将hour转换为1,然后再使用from pyspark.sql.functions import date_trunc, when df.withColumn( "bleeds_into_next_hour", hour(col("endtime")) != hour(col("starttime")) ).withColumn( "endtime", when( col("bleeds_into_next_hour"), date_trunc('hour', "endtime") ).otherwise(col("endtime")) ).show() #+-----+-------------------+-------------------+---------------------+ #| Name| starttime| endtime|bleeds_into_next_hour| #+-----+-------------------+-------------------+---------------------+ #|user1|2019-08-02 03:34:45|2019-08-02 03:52:03| false| #|user2|2019-08-13 13:34:10|2019-08-13 14:00:00| true| #+-----+-------------------+-------------------+---------------------+ 转换回。

endtime

将它们放在一起,没有中间列:

unix_timestamp

Notes

  1. 假设unix_timestamp始终大于或等于from_unixtime。您无法执行from_unixtime,因为小时数会在12点后结束。
© www.soinside.com 2019 - 2024. All rights reserved.