Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 如何在两个不同的列上应用窗口规范(PySpark)_Apache Spark_Pyspark_Spark Dataframe - Fatal编程技术网

Apache spark 如何在两个不同的列上应用窗口规范(PySpark)

Apache spark 如何在两个不同的列上应用窗口规范(PySpark),apache-spark,pyspark,spark-dataframe,Apache Spark,Pyspark,Spark Dataframe,我面临一个问题,从API上看,解决方案对我来说并不明显,我想知道什么是最有效的方法 用例: 我收集了两种类型的tweet,并将它们存储在一个数据帧中(我们称它们为Type1,Type2)。对于这个问题,重要的是它发布的时间戳。对于Type1的每条推文,我需要获取所有Type2的推文,这些推文位于Type1的时间戳周围的某个+/-时间窗口中,并根据每个Type2推文在此时间窗口内的时间增量计算一个度量值 根据我的尝试,时间戳列上的一个简单的WindowSpec在这里无法工作。如果我这样做,我会得到

我面临一个问题,从API上看,解决方案对我来说并不明显,我想知道什么是最有效的方法

用例:

我收集了两种类型的tweet,并将它们存储在一个数据帧中(我们称它们为Type1Type2)。对于这个问题,重要的是它发布的时间戳。对于Type1的每条推文,我需要获取所有Type2的推文,这些推文位于Type1的时间戳周围的某个+/-时间窗口中,并根据每个Type2推文在此时间窗口内的时间增量计算一个度量值

根据我的尝试,时间戳列上的一个简单的WindowSpec在这里无法工作。如果我这样做,我会得到每个时间戳的windowSpec,但我只需要特定的时间戳(Type1s)。我尝试为每种类型的tweet创建两个时间戳列,并按Type1时间戳排序。。但是“rangesBetween”选项似乎只对我排序所依据的列起作用(我需要对Type1时间戳列进行排序,但要在Type2时间戳列之间进行排序)

我提出的一个解决方案是创建两个数据帧,每种类型一个。然后,对于Type1tweet,我将所有时间戳收集到一个列表中,对于每个Type2tweet,我计算该列表中每个时间戳的时间增量并使用它。这是可行的,但在我看来,解决方案效率低下,而且对于足够大的数据帧,收集过程可能会因为内存问题而失败


希望我对问题的描述足够清楚:)

这些可能是重叠的窗口,因此不可能使用
partitionBy
并且帧不能是“动态的”(它们不能基于当前行的时间戳值)

在我看来,您应该使用
Kafka
流式传输twitterapi,并对批处理进行操作。但是既然你已经有了你的数据帧,我们还是试试吧

收集值不是正确的解决方案(它会将所有内容都放在驱动程序的内存中)。另一种可能是进行笛卡尔连接,这非常昂贵,最终会在最终操作中过滤很多行。我们可以通过创建自己的动态批来解决这个问题

首先,让我们为类型tweets 1和2创建两个示例数据帧:

将日期时间导入为dt
将numpy作为np导入
np.random.seed(0)
time_deltas1=np.random.randint(0,10,5).cumsum()
time_deltas2=np.random.randint(0,10,20).cumsum()
df1=spark.createDataFrame(
sc.parallelize(zip)(
[dt.datetime(2017,1,1,0,0,0)+dt.timedelta(分钟=4*int(x))表示x的时间增量1],
[chr(c)表示范围内的c(ord('a')、ord('f'))]
)), 
[“ts1”,“text1”]
)
df2=spark.createDataFrame(
sc.parallelize(zip)(
[dt.datetime(2017,1,1,0,0,0)+dt.timedelta(分钟=int(x))+dt.timedelta(秒=30)表示x的时间增量2],
[chr(c)表示范围内的c(ord('f')、ord('z'))]
)), 
[“ts2”,“text2”]
)
+-------------------+-----+
|ts1 |文本1|
+-------------------+-----+
|2017-01-01 00:20:00 | a|
|2017-01-01 00:20:00 | b|
|2017-01-01 00:32:00 | c|
|2017-01-01 00:44:00 | d|
|2017-01-01 01:12:00 |东|
+-------------------+-----+
+-------------------+-----+
|ts2 |文本2|
+-------------------+-----+
|2017-01-01 00:09:30 | f|
|2017-01-01 00:12:30 | g|
|2017-01-01 00:17:30 | h|
|2017-01-01 00:19:30 | i|
|2017-01-01 00:23:30 | j|
|2017-01-01 00:30:30 | k|
|2017-01-01 00:36:30 | l|
|2017-01-01 00:44:30 | m|
|2017-01-01 00:52:30 | n|
|2017-01-01 00:53:30 | o|
|2017-01-01 00:59:30 | p|
|2017-01-01:06:30 | q|
|2017-01-01:13:30 | r|
|2017-01-01 01:21:30 | s|
|2017-01-01:22:30 | t|
|2017-01-01:27:30 | u|
|2017-01-01 01:36:30 | v|
|2017-01-01 01:44:30西|
|2017-01-01 01:53:30 | x|
|2017-01-01 01:57:30 | y|
+-------------------+-----+
假设我们的窗口应该是+/-
n
minutes,因此我们需要一个
2*n
minute窗口

首先,我们将
时间戳转换为
int
,然后将它们四舍五入到两个最接近的
2*n
分钟时间戳:

import pyspark.sql.函数作为psf
n=5*60#,持续+/-5分钟
df1=df1.withColumn(“ts1”,psf.unix_时间戳(df1.ts1)).withColumn(
“时间范围”,
psf.explode(psf.array((psf.col(“ts1”)/(2*n)).cast(“int”)*(2*n),((1+psf.col(“ts1”)/(2*n)).cast(“int”)*(2*n)))
)
df2=df2.withColumn(“ts2”,psf.unix_时间戳(df2.ts2)).withColumn(
“时间范围”,
psf.explode(psf.array((psf.col(“ts2”)/(2*n)).cast(“int”)*(2*n),((1+psf.col(“ts2”)/(2*n)).cast(“int”)*(2*n)))
)
将unix时间戳转换为时间戳以可视化:

+-------------------+-----+-------------------+
|ts1 |文本1 |时间范围|
+-------------------+-----+-------------------+
|2017-01-01 00:20:00 | a | 2017-01-01 00:20:00|
|2017-01-01 00:20:00 | a | 2017-01-01 00:30:00|
|2017-01-01 00:20:00 | b | 2017-01-01 00:20:00|
|2017-01-01 00:20:00 | b | 2017-01-01 00:30:00|
|2017-01-01 00:32:00 | c | 2017-01-01 00:30:00|
|2017-01-01 00:32:00 | c | 2017-01-01 00:40:00|
|2017-01-01 00:44:00 | d | 2017-01-01 00:40:00|
|2017-01-01 00:44:00 | d | 2017-01-01 00:50:00|
|2017-01-01 01:12:00 | e | 2017-01-01 01:10:00|
|2017-01-01 01:12:00 | e | 2017-01-01 01:20:00|
+-------------------+-----+-------------------+
+-------------------+-----+-------------------+
|ts2 |文本2 |时间范围|
+-------------------+-----+-------------------+
|2017-01-01 00:09:30 | f | 2017-01-01 00:00:00|
|2017-01-01 00:09:30 | f