不使用ID创建新的spark DataFrame列

不使用ID创建新的spark DataFrame列,dataframe,apache-spark,pyspark,apache-spark-sql,Dataframe,Apache Spark,Pyspark,Apache Spark Sql,我有一个关于连接日志的数据框,其中包含列targetIP,Time。此数据帧中的每个记录都是到一个系统的连接事件targetIP表示这次的目标IP地址,time是连接时间。价值观: 时间 目标 1. 192.163.0.1 2. 192.163.0.2 3. 192.163.0.1 5. 192.163.0.1 6. 192.163.0.2 7. 192.163.0.2 8. 192.163.0.2 您可以使用row\u number分配ID: from pyspark.sql import f

我有一个关于连接日志的数据框,其中包含列
targetIP
Time
。此数据帧中的每个记录都是到一个系统的连接事件
targetIP
表示这次的目标IP地址,time是连接时间。价值观:

时间 目标 1. 192.163.0.1 2. 192.163.0.2 3. 192.163.0.1 5. 192.163.0.1 6. 192.163.0.2 7. 192.163.0.2 8. 192.163.0.2
您可以使用
row\u number
分配ID:

from pyspark.sql import functions as F, Window

df2 = df.withColumn(
    'id',
    F.row_number().over(Window.orderBy('Time'))
).withColumn(
    'count', 
    F.count('*').over(
        Window.partitionBy('targetIP').orderBy('id').rangeBetween(-3,-1)
    )
).orderBy('Time')

df2.show()
+----+-----------+---+-----+
|Time|   targetIP| id|count|
+----+-----------+---+-----+
|   1|192.163.0.1|  1|    0|
|   2|192.163.0.2|  2|    0|
|   3|192.163.0.1|  3|    1|
|   5|192.163.0.1|  4|    2|
|   6|192.163.0.2|  5|    1|
|   7|192.163.0.2|  6|    1|
|   8|192.163.0.2|  7|    2|
+----+-----------+---+-----+
另一种不使用ID的方法是执行
收集\u列表
并过滤生成的数组:

from pyspark.sql import functions as F, Window

df2 = df.withColumn(
    'count',
    F.expr("""
        size(filter(
            collect_list(targetIP) over (order by Time rows between 3 preceding and 1 preceding),
            x -> x = targetIP
        ))
    """)
)

df2.show()
+----+-----------+-----+
|Time|   targetIP|count|
+----+-----------+-----+
|   1|192.163.0.1|    0|
|   2|192.163.0.2|    0|
|   3|192.163.0.1|    1|
|   5|192.163.0.1|    2|
|   6|192.163.0.2|    1|
|   7|192.163.0.2|    1|
|   8|192.163.0.2|    2|
+----+-----------+-----+

您可以使用
row\u number
分配ID:

from pyspark.sql import functions as F, Window

df2 = df.withColumn(
    'id',
    F.row_number().over(Window.orderBy('Time'))
).withColumn(
    'count', 
    F.count('*').over(
        Window.partitionBy('targetIP').orderBy('id').rangeBetween(-3,-1)
    )
).orderBy('Time')

df2.show()
+----+-----------+---+-----+
|Time|   targetIP| id|count|
+----+-----------+---+-----+
|   1|192.163.0.1|  1|    0|
|   2|192.163.0.2|  2|    0|
|   3|192.163.0.1|  3|    1|
|   5|192.163.0.1|  4|    2|
|   6|192.163.0.2|  5|    1|
|   7|192.163.0.2|  6|    1|
|   8|192.163.0.2|  7|    2|
+----+-----------+---+-----+
另一种不使用ID的方法是执行
收集\u列表
并过滤生成的数组:

from pyspark.sql import functions as F, Window

df2 = df.withColumn(
    'count',
    F.expr("""
        size(filter(
            collect_list(targetIP) over (order by Time rows between 3 preceding and 1 preceding),
            x -> x = targetIP
        ))
    """)
)

df2.show()
+----+-----------+-----+
|Time|   targetIP|count|
+----+-----------+-----+
|   1|192.163.0.1|    0|
|   2|192.163.0.2|    0|
|   3|192.163.0.1|    1|
|   5|192.163.0.1|    2|
|   6|192.163.0.2|    1|
|   7|192.163.0.2|    1|
|   8|192.163.0.2|    2|
+----+-----------+-----+