如何使用pyspark从一个月的某一天获得工作日

mdi*_*ivk 6 dayofweek apache-spark pyspark

我有一个dataframe log_df: 在此输入图像描述

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

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)
Run Code Online (Sandbox Code Playgroud)

新的数据框如下: 在此输入图像描述

我需要另一个列显示每周的日子,创建它的最佳方式是什么?理想情况下,只需在选择中添加类似udf的字段.

非常感谢你.

更新:我的问题与评论中的问题不同,我需要的是根据log_df中的字符串进行计算,而不是基于注释之类的时间戳,所以这不是一个重复的问题.谢谢.

Kar*_*rik 20

我建议采用一种不同的方法

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()
Run Code Online (Sandbox Code Playgroud)

它给 ...

+--------------------+----------+----------+
|         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|
Run Code Online (Sandbox Code Playgroud)


小智 16

从 Spark 2.3 开始,您可以使用 dayofweek 函数 https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.functions.dayofweek.html

from pyspark.sql.functions import dayofweek
df.withColumn('day_of_week', dayofweek('my_timestamp'))
Run Code Online (Sandbox Code Playgroud)

然而,这将一周的开始定义为星期日 = 1

如果您不希望这样,而是要求 Monday = 1,那么您可以做一个不优雅的忽悠,例如在使用 dayofweek 函数之前减去 1 天,或者修改结果,如下所示

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


mdi*_*ivk -5

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

  1. 导入日期格式、日期时间、数据类型
  2. 首先,修改正则表达式以提取 01/Jul/1995
  3. 使用 func 将 01/Jul/1995 转换为 DateType
  4. 创建 udf dayOfWeek 以获取简短格式的工作日(周一、周二……)
  5. 使用 udf 将 DateType 01/Jul/1995 转换为工作日,即 Sat 在此输入图像描述

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