Pyspark drop_duplicates(keep = False)

时间:2019-01-09 18:45:19

标签: python pandas pyspark duplicates

我需要用于熊猫-1 = true/yes, 0=false/no Pyspark 解决方案。不幸的是,drop_duplicates(keep=False)选项在pyspark中不可用...

熊猫示例:

keep=False

预期输出:

import pandas as pd

df_data = {'A': ['foo', 'foo', 'bar'], 
         'B': [3, 3, 5],
         'C': ['one', 'two', 'three']}
df = pd.DataFrame(data=df_data)
df = df.drop_duplicates(subset=['A', 'B'], keep=False)
print(df)

无法进行 A B C 2 bar 5 three 转换并返回pyspark。

谢谢!

2 个答案:

答案 0 :(得分:1)

使用窗口函数计算每个A / B组合的行数,然后过滤结果以仅保留唯一的行:

import pyspark.sql.functions as f

df.selectExpr(
  '*', 
  'count(*) over (partition by A, B) as cnt'
).filter(f.col('cnt') == 1).drop('cnt').show()

+---+---+-----+
|  A|  B|    C|
+---+---+-----+
|bar|  5|three|
+---+---+-----+

或使用pandas_udf的另一个选项:

from pyspark.sql.functions import pandas_udf, PandasUDFType

# keep_unique returns the data frame if it has only one row, otherwise 
# drop the group
@pandas_udf(df.schema, PandasUDFType.GROUPED_MAP)
def keep_unique(df):
    return df.iloc[:0] if len(df) > 1 else df

df.groupBy('A', 'B').apply(keep_unique).show()
+---+---+-----+
|  A|  B|    C|
+---+---+-----+
|bar|  5|three|
+---+---+-----+

答案 1 :(得分:0)

简单的方法是对此类行进行计数,然后仅选择出现一次的行,以避免重复的任何行,然后删除多余的列。

df= df.groupBy('A', 'B').agg(f.expr('count(*)').alias('Frequency'))
df=df.select('*').where(df.Frequency==1)
df=df.drop('Frequency')