Присвоить значения столбцам на основе условий pyspark - PullRequest
0 голосов
/ 18 октября 2018

Я использую pyspark для анализа большого количества данных.У меня есть кадр данных, который имеет следующие столбцы

ip_address device_id location device_type

Я хочу создать новый столбец с именем id и назначить те же значенияid для столбцов, которые удовлетворяют одному из следующих условий

1) они имеют одинаковые device_id и ip_address

2) они имеют одинаковые device_id, locationи device_type

3) они имеют одинаковые ip_address, location и device_type

В принципе, я хочу найти все те строки, которые представляют одно и то же устройство на основеВышеуказанное условие и присвойте им тот же идентификатор

. Допустим, у меня есть следующие столбцы

+--------+-----------+------------+-----------+-------------+ | number | device_id | ip_address | location | device_type | +--------+-----------+------------+-----------+-------------+ | 1 | device1 | ip1 | location1 | type1 | | 2 | device1 | ip1 | location1 | type1 | | 3 | device1 | ip2 | location1 | type1 | | 4 | device2 | ip1 | location1 | type1 | | 5 | device3 | ip3 | location2 | type2 | +--------+-----------+------------+-----------+-------------+

Первые 4 строки должны быть одинаковыми idкаждая строка соответствует одному из трех условий.

строки 1 и 2 удовлетворяют условию 1

строки 2 и 3 удовлетворяют условию 2

, а строки 3 и 4 удовлетворяют условию 3

Таким образом, выходной сигнал должен быть

+--------+-----------+------------+-----------+-------------+----+ | number | device_id | ip_address | location | device_type | id | +--------+-----------+------------+-----------+-------------+----+ | 1 | device1 | ip1 | location1 | type1 | 1 | | 2 | device1 | ip1 | location1 | type1 | 1 | | 3 | device1 | ip2 | location1 | type1 | 1 | | 4 | device2 | ip1 | location1 | type1 | 1 | | 5 | device3 | ip3 | location2 | type2 | 2 | +--------+-----------+------------+-----------+-------------+----+

Этого вообще возможно достичь?и если да, то как мне это сделать?

1 Ответ

0 голосов
/ 18 октября 2018

Вы можете сделать это.Не уверен, что это идеальный способ, но он работает:

df = spark.createDataFrame([
("1" ,   "device1"   ,   "ip1"        ,  "location1" ,   "type1"),
("2" ,   "device1"   ,   "ip1"        ,  "location1" ,   "type1"),
("3" ,   "device1"   ,   "ip2"        ,  "location1" ,   "type1"),
("4" ,   "device2"   ,   "ip1"        ,  "location1" ,   "type1"),
("5" ,   "device3"   ,   "ip3"        ,  "location2" ,   "type2")
], ("ip_address", "device_id", "location", "device_type"))

df1 = df.groupBy("device_id","ip_address").agg(min(col("number"))).select(col("device_id").alias("d_id"), col("ip_address").alias("ip"), col("min(number)").alias("id1"))
df2 = df.groupBy("device_id","location","device_type").agg(min(col("number"))).select(col("device_id").alias("d_id"), col("location").alias("l"), col("device_type").alias("d_type"), col("min(number)").alias("id2"))
df3 = df.groupBy("ip_address","location","device_type").agg(min(col("number"))).select(col("ip_address").alias("ip"), col("location").alias("l"), col("device_type").alias("d_type"), col("min(number)").alias("id3"))

df.join(df1, [(df1.d_id == df.device_id) & (df1.ip == df.ip_address)], how="inner").select("number","device_id","ip_address","location","device_type","id1").join(df2, [(df2.d_id == df.device_id) & (df2.l == df.location) & (df2.d_type == df.device_type)], how="inner").select("number","device_id","ip_address","location","device_type","id1","id2").join(df3, [(df3.ip == df.ip_address) & (df3.l == df.location) & (df3.d_type == df.device_type)], how="inner").select("number","device_id","ip_address","location","device_type","id1","id2","id3").withColumn("id",least(col("id1"),col("id2"),col("id3"))).show()

Условия соединения соответствуют вашим желаемым условиям.Результат находится в последнем столбце id и выглядит следующим образом:

+------+---------+----------+---------+-----------+---+---+---+---+  
|number|device_id|ip_address| location|device_type|id1|id2|id3| id| 
+------+---------+----------+---------+-----------+---+---+---+---+ 
| 5    | device3 | ip3      |location2| type2     | 5 | 5 | 5 | 5 | 
| 3    | device1 | ip2      |location1| type1     | 3 | 1 | 3 | 1 | 
| 4    | device2 | ip1      |location1| type1     | 4 | 4 | 1 | 1 | 
| 1    | device1 | ip1      |location1| type1     | 1 | 1 | 1 | 1 | 
| 2    | device1 | ip1      |location1| type1     | 1 | 1 | 1 | 1 | 
+------+---------+----------+---------+-----------+---+---+---+---+
...