Python 根据PySpark中不同列的重复条目中的列值选择行
我有一个PySpark数据帧,我将其分组在一个字段(列)上,目的是消除每个组中具有另一个字段特定值的记录。 例如,这个表看起来像Python 根据PySpark中不同列的重复条目中的列值选择行,python,sql,apache-spark,aggregate,pyspark,Python,Sql,Apache Spark,Aggregate,Pyspark,我有一个PySpark数据帧,我将其分组在一个字段(列)上,目的是消除每个组中具有另一个字段特定值的记录。 例如,这个表看起来像 colA colB 'a' 1 'b' 1 'a' 0 'c' 0 在这里,我想要的是删除记录,其中有一个重复的colA,colB是0,所以要获得 colA colB 'a' 1 'b' 1 'c' 0 “c”的行仍然保留,因为我只想删除重复(在colA上)行的0 我想不出一个方法来实现这一点,因
colA colB
'a' 1
'b' 1
'a' 0
'c' 0
在这里,我想要的是删除记录,其中有一个重复的colA,colB是0,所以要获得
colA colB
'a' 1
'b' 1
'c' 0
“c”的行仍然保留,因为我只想删除重复(在colA上)行的0
我想不出一个方法来实现这一点,因为我不擅长在
groupBy
之后使用agg
,如果expr
不是“avg”、“max”等中的一个,那么简单的max
怎么样
从pyspark.sql.functions导入max作为max_
df=sc.parallelize([
('a',1),('b',1),('a',0),('c',0)
]).toDF(('colA','colB'))
df.groupBy('colA').agg(max_('colB')).show()
## +----+---------+
##|可乐|马克斯(可乐)|
## +----+---------+
##| a | 1|
##| b | 1|
##| c | 0|
## +----+---------+
这种方法应该适用于任何支持排序并使用二进制标签的列,其中包含对所用聚合函数的可选调整(min
/max
)
可以使用窗口函数实现更高级的规则,但代价会更高
然而,这里有一个例子:
from pyspark.sql.functions import col, sum as sum_, when
from pyspark.sql import Window
import sys
w = Window.partitionBy("colA").rowsBetween(-sys.maxsize, sys.maxsize)
this_non_zero = col("colB") != 0
any_non_zero = sum_(this_non_zero.cast("long")).over(w) != 0
(df
.withColumn("this_non_zero", this_non_zero)
.withColumn("any_non_zero", any_non_zero)
.where(
(col("this_non_zero") & col("any_non_zero")) |
~col("any_non_zero")
))
简单的
max
怎么样
从pyspark.sql.functions导入max作为max_
df=sc.parallelize([
('a',1),('b',1),('a',0),('c',0)
]).toDF(('colA','colB'))
df.groupBy('colA').agg(max_('colB')).show()
## +----+---------+
##|可乐|马克斯(可乐)|
## +----+---------+
##| a | 1|
##| b | 1|
##| c | 0|
## +----+---------+
这种方法应该适用于任何支持排序并使用二进制标签的列,其中包含对所用聚合函数的可选调整(min
/max
)
可以使用窗口函数实现更高级的规则,但代价会更高
然而,这里有一个例子:
from pyspark.sql.functions import col, sum as sum_, when
from pyspark.sql import Window
import sys
w = Window.partitionBy("colA").rowsBetween(-sys.maxsize, sys.maxsize)
this_non_zero = col("colB") != 0
any_non_zero = sum_(this_non_zero.cast("long")).over(w) != 0
(df
.withColumn("this_non_zero", this_non_zero)
.withColumn("any_non_zero", any_non_zero)
.where(
(col("this_non_zero") & col("any_non_zero")) |
~col("any_non_zero")
))
你也可以检查和其他一些想法。但是在这里我不想麻烦。不要:)
max
/min
应该直接工作,但是如果你想显式地使用像when(col(“colA”)=“foo”,0)这样的东西。否则(1)
这太棒了!我能问一下max和min是怎么工作的吗,他们计算了字符串长度的max/min吗?对于max,我得到的是a的最短字符串,而min的最长字符串(在您的示例中,假设1和0变成“保存”和“隐藏”:对于max,得到的是“保存”,对于min,得到的是“隐藏”,所以我很困惑)。假设没有大小写混合的字符串,也没有本地化的字符串,那么它将按照字母顺序排列。所以h
出现在s
之前:)您还可以查看和了解其他一些想法。但是在这里我不想麻烦。不要:)max
/min
应该直接工作,但是如果你想显式地使用像when(col(“colA”)=“foo”,0)这样的东西。否则(1)
这太棒了!我能问一下max和min是怎么工作的吗,他们计算了字符串长度的max/min吗?对于max,我得到的是a的最短字符串,而min的最长字符串(在您的示例中,假设1和0变成“保存”和“隐藏”:对于max,得到的是“保存”,对于min,得到的是“隐藏”,所以我很困惑)。假设没有大小写混合的字符串,也没有本地化的字符串,那么它将按照字母顺序排列。所以h
在s
之前