如何使用窗口函数计算Pyspark 2.1中每周发生的天数

如何使用窗口函数计算Pyspark 2.1中每周发生的天数,pyspark,window,apache-spark-2.1.1,Pyspark,Window,Apache Spark 2.1.1,在下面的pyspark数据集(2.1)中,如何使用一个窗口函数来计算最近28天内当前记录的星期几出现的次数 示例数据帧: from pyspark.sql import functions as F df = sqlContext.createDataFrame([ ("a", "1", "2018-01-01 12:01:01","Monday"), ("a", "13", "2018-01-01 14:01:01","Monday"), ("a", "

在下面的pyspark数据集(2.1)中,如何使用一个窗口函数来计算最近28天内当前记录的星期几出现的次数

示例数据帧:

from pyspark.sql import functions as F
df = sqlContext.createDataFrame([
    ("a", "1", "2018-01-01 12:01:01","Monday"),
        ("a", "13", "2018-01-01 14:01:01","Monday"),
        ("a", "22", "2018-01-02 22:01:01","Tuesday"),
        ("a", "43", "2018-01-08 01:01:01","Monday"),
        ("a", "43", "2018-01-09 01:01:01","Tuesday"),
        ("a", "74", "2018-01-10 12:01:01","Wednesday"),
        ("a", "95", "2018-01-15 06:01:01","Monday"),
], ["person_id", "other_id", "timestamp","dow"])


df.withColumn("dow_count",`some window function`)
可能窗口

from pyspark.sql import Window
from pyspark.sql import functions as F
Days_28 = (86400 * 28)
window= Window.partitionBy("person_id").orderBy('timestamp').rangeBetween(-Days_30, -1)
## I know this next line is wrong
df.withColumn("dow_count",F.sum(F.when(Current_day=windowed_day,1).otherwise(0)).over(window))
示例输出

df.show()

+---------+--------+-------------------+---------+---------+
|person_id|other_id|          timestamp|      dow|dow_count|
+---------+--------+-------------------+---------+---------+
|        a|       1|2018-01-01 12:01:01|   Monday|0        |
|        a|      13|2018-01-01 14:01:01|   Monday|1        |
|        a|      22|2018-01-02 22:01:01|  Tuesday|0        |
|        a|      43|2018-01-08 01:01:01|   Monday|2        |
|        a|      43|2018-01-09 01:01:01|  Tuesday|1        |
|        a|      74|2018-01-10 12:01:01|Wednesday|0        |
|        a|      95|2018-01-15 06:01:01|   Monday|3        |
+---------+--------+-------------------+---------+---------+
使用F.行编号(),窗口分区为(person\u id,dow),您的
rangeBetween()的逻辑应替换为
where()

从datetime导入timedelta,datetime
N_天=28天
end=datetime.combine(datetime.today(),datetime.min.time())
开始=结束-时间增量(天=N天)
window=window.partitionBy(“person\u id”,“dow”).orderBy(“timestamp”)
其中((df.timestamp=start))\
.withColumn('dow_count',F.row_number()。在(窗口)-1上方)\
.show()
使用F.row_number()、按(person_id,dow)分区的窗口,并且您的
rangeBetween()的逻辑应替换为
where()

从datetime导入timedelta,datetime
N_天=28天
end=datetime.combine(datetime.today(),datetime.min.time())
开始=结束-时间增量(天=N天)
window=window.partitionBy(“person\u id”,“dow”).orderBy(“timestamp”)
其中((df.timestamp=start))\
.withColumn('dow_count',F.row_number()。在(窗口)-1上方)\
.show()

我想出来了,想和大家分享一下

首先创建一个unix时间戳并将其强制转换为long。 然后,按人和星期几划分。 最后,在窗口上使用count函数

from pyspark.sql import functions as F
df = df.withColumn('unix_ts',df.timestamp.astype('Timestamp').cast("long"))

w = Window.partitionBy('person_id','dow').orderBy('unix_ts').rangeBetween(-86400*15,-1)
df = df.withColumn('occurrences_in_7_days',F.count('unix_ts').over(w))
df.sort(df.unix_ts).show()
奖励:如何从时间戳创建实际的星期几

df = df.withColumn("DayOfWeek",F.date_format(df.timestamp, 'EEEE'))

如果没有jxc和stackoverflow文章中的提示,我不可能做到这一点。

我想我会与大家分享

首先创建一个unix时间戳并将其强制转换为long。 然后,按人和星期几划分。 最后,在窗口上使用count函数

from pyspark.sql import functions as F
df = df.withColumn('unix_ts',df.timestamp.astype('Timestamp').cast("long"))

w = Window.partitionBy('person_id','dow').orderBy('unix_ts').rangeBetween(-86400*15,-1)
df = df.withColumn('occurrences_in_7_days',F.count('unix_ts').over(w))
df.sort(df.unix_ts).show()
奖励:如何从时间戳创建实际的星期几

df = df.withColumn("DayOfWeek",F.date_format(df.timestamp, 'EEEE'))

如果没有jxc和stackoverflow文章中的提示,我不可能做到这一点。

问题是,它会将每行中的日期与当前时间戳进行比较,而不是将每行倒计时28天。但是每行只能保存一个
dow_count
,除非在数据框中再添加27列或行。这就是你想要的吗?啊,我明白了,你每周每天都在写专栏。是的,每一行只需要道琼斯指数,特别是当前的星期几。所以如果今天是周一,那么我只需要过去28天周一的道指,我现在就知道了。“道”的划分帮助很大。我最终创建了一个unix,将其强制转换为long,并在窗口上使用计数。问题是,它将每行中的日期与当前时间戳进行比较,而不是将每行向后计数28天。但每行只能保存一个
道计数
,除非在数据帧中再添加27列或行。这就是你想要的吗?啊,我明白了,你每周每天都在写专栏。是的,每一行只需要道琼斯指数,特别是当前的星期几。所以如果今天是周一,那么我只需要过去28天周一的道指,我现在就知道了。“道”的划分帮助很大。我最终创建了一个unix,将其转换为long并在窗口上使用计数。