For Spark 2.4+ you can use array functions and higher-order functions. This solution will work for different array sizes (event if different between each row). Here are the steps explained:
First, group by 2 seconds and collect the vars in an array column :
df = df.groupBy((ceil(col("timestamp") / 2) * 2).alias("timestamp")) \
.agg(collect_list(col("vars")).alias("vars"))
df.show()
#+---------+----------------------+
#|timestamp|vars |
#+---------+----------------------+
#|6 |[[1, 1, 1], [1, 2, 3]]|
#|2 |[[1, 1, 1], [1, 2, 1]]|
#|4 |[[1, 1, 1], [1, 3, 4]]|
#+---------+----------------------+
Here we grouped each consecutive 2 seconds and collected the vars arrays into a new list.
Now, using a Window spec you can collect cumulative values and use flatten to flatten the sub arrays:
w = Window.orderBy("timestamp").rowsBetween(Window.unboundedPreceding, Window.currentRow)
df = df.withColumn("vars", flatten(collect_list(col("vars")).over(w)))
df.show()
#+---------+------------------------------------------------------------------+
#|timestamp|vars |
#+---------+------------------------------------------------------------------+
#|2 |[[1, 1, 1], [1, 2, 1]] |
#|4 |[[1, 1, 1], [1, 2, 1], [1, 1, 1], [1, 3, 4]] |
#|6 |[[1, 1, 1], [1, 2, 1], [1, 1, 1], [1, 3, 4], [1, 1, 1], [1, 2, 3]]|
#+---------+------------------------------------------------------------------+
Finally, use aggregate function with zip_with to sum the arrays :
t = "aggregate(vars, cast(array() as array<double>), (acc, a) -> zip_with(acc, a, (x, y) -> coalesce(x, 0) + coalesce(y, 0)))"
df.withColumn("vars", expr(t)).show(truncate=False)
#+---------+-----------------+
#|timestamp|vars |
#+---------+-----------------+
#|2 |[2.0, 3.0, 2.0] |
#|4 |[4.0, 7.0, 7.0] |
#|6 |[6.0, 10.0, 11.0]|
#+---------+-----------------+
Putting all together:
from pyspark.sql.functions import ceil, col, collect_list, flatten, expr
from pyspark.sql import Window
w = Window.orderBy("timestamp").rowsBetween(Window.unboundedPreceding, Window.currentRow)
t = "aggregate(vars, cast(array() as array<double>), (acc, a) -> zip_with(acc, a, (x, y) -> coalesce(x, 0) + coalesce(y, 0)))"
nb_seconds = 2
df.groupBy((ceil(col("timestamp") / nb_seconds) * nb_seconds).alias("timestamp")) \
.agg(collect_list(col("vars")).alias("vars")) \
.withColumn("vars", flatten(collect_list(col("vars")).over(w))) \
.withColumn("vars", expr(t)).show(truncate=False)