我在pyspark
中有一个数据框,如下所示。
+---+-------------+------------+
| id| device| model|
+---+-------------+------------+
| 3| mac pro| mac|
| 1| iphone| iphone5|
| 1|android phone| android|
| 1| windows pc| windows|
| 1| spy camera| spy camera|
| 2| | camera|
| 3| cctv| cctv|
| 2| iphone|apple iphone|
| 3| spy camera| |
+---+-------------+------------+
我想通过在每个column
的{{1}}列中连接唯一值来创建device and model
我在下面做了
首先连接两个id
列
device and model
然后按df1 = df.select(col("id"), concat(col("model"), lit(","), col("device")).alias('con'))
+---+--------------------+
| id| con|
+---+--------------------+
| 3| mac,mac pro|
| 1| iphone5,iphone|
| 1|android,android p...|
| 1| windows,windows pc|
| 1|spy camera,spy ca...|
| 2| camera,|
| 3| cctv,cctv|
| 2| apple iphone,iphone|
| 3| ,spy camera|
+---+--------------------+
groupBy
id
但我在结果中得到重复的值。如何避免在最终数据框中填充重复值
答案 0 :(得分:2)
您可以使用collect_set
和udf
功能删除重复项
from pyspark.sql import functions as f
from pyspark.sql import types as t
def uniqueStringUdf(device, model):
return ','.join(set(filter(bool, device + model)))
uniqueStringUdfCall = f.udf(uniqueStringUdf, t.StringType())
df.groupBy("id").agg(uniqueStringUdfCall(f.collect_set("device"), f.collect_set("model")).alias("con")).show(truncate=False)
应该给你
+---+------------------------------------------------------------------+
|id |con |
+---+------------------------------------------------------------------+
|3 |spy camera,mac,mac pro,cctv |
|1 |spy camera,windows,iphone5,windows pc,iphone,android phone,android|
|2 |camera,iphone,pple iphone |
+---+------------------------------------------------------------------+
其中,
device + model
是两个收集集的串联
filter(bool, device + model)
正在从连接列表中删除空字符串
set(filter(bool, device + model))
删除连接列表中的重复字符串
','.join(set(filter(bool, device + model)))
将连接列表的所有元素连接到以逗号分隔的字符串。
我希望答案很有帮助
答案 1 :(得分:2)
使用F.array()
,F.explode()
和F.collect_set()
:
from pyspark.sql import functions as F
df.withColumn('con', F.explode(F.array('device', 'model'))) \
.groupby('id').agg(F.collect_set('con').alias('Group_con')) \
.show(3,0)
# +---+--------------------------------------------------------------------------+
# |id |Group_con |
# +---+--------------------------------------------------------------------------+
# |3 |[cctv, mac pro, spy camera, mac] |
# |1 |[windows pc, iphone5, windows, iphone, android phone, spy camera, android]|
# |2 |[apple iphone, camera, iphone] |
# +---+--------------------------------------------------------------------------+
(在火花版2.2.1上测试)
答案 2 :(得分:0)
不确定这是否会非常有用。但我能想到的一个解决方案是检查列中的重复值,然后使用它们的位置/索引删除它们。
或
将所有值拆分为逗号","列出并通过比较每个值删除所有重复项。或者count()一个值的出现,如果它超过1,则删除除第一个之外的所有重复项。
很抱歉,如果这没有帮助。这是我能想到解决问题的两种方法。