Apache spark 如何使用pyspark从月份的第几天获取工作日

Apache spark 如何使用pyspark从月份的第几天获取工作日,apache-spark,pyspark,dayofweek,Apache Spark,Pyspark,Dayofweek,我有一个数据帧日志: 我根据以下代码生成一个新的数据帧: from pyspark.sql.functions import split, regexp_extract split_log_df = log_df.select(regexp_extract('value', r'^([^\s]+\s)', 1).alias('host'), regexp_extract('value', r'^.*\[(\d\d/\w{3}/\d{4}:\

我有一个数据帧日志:

我根据以下代码生成一个新的数据帧:

from pyspark.sql.functions import split, regexp_extract 
split_log_df = log_df.select(regexp_extract('value', r'^([^\s]+\s)', 1).alias('host'),
                          regexp_extract('value', r'^.*\[(\d\d/\w{3}/\d{4}:\d{2}:\d{2}:\d{2} -\d{4})]', 1).alias('timestamp'),
                          regexp_extract('value', r'^.*"\w+\s+([^\s]+)\s+HTTP.*"', 1).alias('path'),
                          regexp_extract('value', r'^.*"\s+([^\s]+)', 1).cast('integer').alias('status'),
                          regexp_extract('value', r'^.*\s+(\d+)$', 1).cast('integer').alias('content_size'))
split_log_df.show(10, truncate=False)
新的数据帧如下所示:

我需要另一个专栏来展示星期几,最好的优雅方式是什么?理想情况下,只需在select中添加一个类似udf的字段

多谢各位


更新:我的问题与注释中的问题不同,我需要的是基于log_df中的字符串进行计算,而不是像注释那样基于时间戳,因此这不是重复的问题。谢谢。

我终于自己解决了这个问题,以下是完整的解决方案:

  • 导入日期\格式、日期时间、数据类型
  • 首先,将regexp修改为extract 01/Jul/1995
  • 使用func将1995年7月1日转换为日期类型
  • 创建一个udf dayOfWeek,以简短的格式获取星期一(周一、周二等)
  • 使用udf将日期类型01/Jul/1995转换为星期六

  • 我对我的解决方案不满意,因为它看起来很曲折,如果有人能想出一个更优雅的解决方案,我将不胜感激,提前谢谢你。

    我建议一个稍微不同的方法

    from pyspark.sql.functions import date_format
    df.select('capturetime', date_format('capturetime', 'u').alias('dow_number'), date_format('capturetime', 'E').alias('dow_string'))
    df3.show()
    
    它给

    +--------------------+----------+----------+
    |         capturetime|dow_number|dow_string|
    +--------------------+----------+----------+
    |2017-06-05 10:05:...|         1|       Mon|
    |2017-06-05 10:05:...|         1|       Mon|
    |2017-06-05 10:05:...|         1|       Mon|
    |2017-06-05 10:05:...|         1|       Mon|
    |2017-06-05 10:05:...|         1|       Mon|
    |2017-06-05 10:05:...|         1|       Mon|
    |2017-06-05 10:05:...|         1|       Mon|
    |2017-06-05 10:05:...|         1|       Mon|
    

    我这样做是为了从日期开始获得工作日:

    def get_weekday(date):
        import datetime
        import calendar
        month, day, year = (int(x) for x in date.split('/'))    
        weekday = datetime.date(year, month, day)
        return calendar.day_name[weekday.weekday()]
    
    spark.udf.register('get_weekday', get_weekday)
    
    用法示例:

    df.createOrReplaceTempView("weekdays")
    df = spark.sql("select DateTime, PlayersCount, get_weekday(Date) as Weekday from weekdays")
    

    自Spark 2.3以来,您可以使用dayofweek功能

    但是,这将一周的开始定义为周日=1

    如果您不希望这样,而是要求Monday=1,那么您可以在使用dayofweek函数之前减去1天,或者像这样修改结果

    from pyspark.sql.functions import dayofweek
    df.withColumn('day_of_week', ((dayofweek('my_timestamp')+5)%7)+1)
    

    编写一个使用python
    datetime
    模块的UDF python函数,并解析出
    timestamp
    列。可能重复@cricket_007,这正是我在这里寻求帮助的原因,谢谢。您可以将timestamp列重新格式化/转换为Spark接受的日期格式。。。那么这个问题实际上是重复的。您不需要正则表达式提取日期字符串,它有一个标准格式,您可以使用
    datetime.strtime
    for@cricket_007谢谢你能在这里提供你的完整脚本吗?我真的不满意我自己的解决方案张贴在下面这是'u'选项消失了吗?看起来是这样,在火花3.0'u'不存在。Spark 3.0建议将Spark.sql.legacy.timeParserPolicy设置为legacy以获取旧行为。请随时更新答案并发布不带“u”的最新解决方案。我不再和Pypark一起工作了。谢谢您可以使用“E”获取星期几的字符串版本,
    from pyspark.sql.functions import dayofweek
    df.withColumn('day_of_week', ((dayofweek('my_timestamp')+5)%7)+1)