我根据以下代码生成新的数据框:
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)
我需要另一个列显示每周的日子,创建它的最佳方式是什么?理想情况下,只需在选择中添加类似udf的字段。
非常感谢。
更新:我的问题与评论中的问题不同,我需要的是根据log_df中的字符串进行计算,而不是基于评论的时间戳,所以这不是一个重复的问题。感谢。
答案 0 :(得分:16)
我建议采用一种不同的方法
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|
答案 1 :(得分:2)
从 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'))
然而,这将一周的开始定义为星期日 = 1
如果你不想那样,而是要求 Monday = 1,那么你可以做一个不雅的软糖,比如在使用 dayofweek 函数之前减去 1 天,或者像这样修改结果
from pyspark.sql.functions import dayofweek
df.withColumn('day_of_week', ((dayofweek('my_timestamp')+5)%7)+1)
答案 2 :(得分:0)
我终于自己解决了这个问题,这是完整的解决方案:
答案 3 :(得分:0)
我这样做是为了从平日起的工作日:
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")
答案 4 :(得分:0)
由于SPARK 1.5.0具有date_format函数,该函数接受格式作为参数。此格式从时间戳返回星期几的名称:
select date_format(my_timestamp, 'EEEE') from ....
结果:例如“星期二”
答案 5 :(得分:0)
这对我有用:
重新创建与您的示例类似的数据:
df = spark.createDataFrame(\
[(1, "2017-11-01 22:05:01 -0400")\
,(2, "2017-11-02 03:15:16 -0500")\
,(3, "2017-11-03 19:32:24 -0600")\
,(4, "2017-11-04 07:47:44 -0700")\
], ("id", "date"))
df.toPandas()
id date
0 1 2017-11-01 22:05:01 -0400
1 2 2017-11-02 03:15:16 -0500
2 3 2017-11-03 19:32:24 -0600
3 4 2017-11-04 07:47:44 -0700
创建lambda函数来处理到星期的转换
funcWeekDay = udf(lambda x: datetime.strptime(x, '%Y-%m-%d').strftime('%w'))
shortdate
列中shortdate
列代码:
from pyspark.sql.functions import udf,col
from datetime import datetime
df=df.withColumn('shortdate',col('date').substr(1, 10))\
.withColumn('weekDay', funcWeekDay(col('shortdate')))\
.drop('shortdate')
结果:
df.toPandas()
id date weekDay
0 1 2017-11-01 22:05:01 -0400 3
1 2 2017-11-02 03:15:16 -0500 4
2 3 2017-11-03 19:32:24 -0600 5
3 4 2017-11-04 07:47:44 -0700 6