> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prophecy.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Deduplicate gem for Data Engineering

> Remove rows with duplicate values of specified columns

<Panel>
  <Info>
    Dependencies:

    * ProphecySparkBasicsPython 0.0.1+
    * ProphecySparkBasicsScala 0.0.1+
  </Info>

  <Info>
    Cluster requirements:

    * UC dedicated clusters 14.3+ supported
    * UC standard clusters 14.3+ supported
    * Livy clusters 3.0.1+ supported
  </Info>
</Panel>

Removes rows with duplicate values of specified columns.

## Parameters

| Parameter           | Description                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| DataFrame           | Input DataFrame                                                                                                                                                                                                                                                                                                                                                                                                     |
| Row to keep         | <ul><li>Any (Default): Keeps any one row among duplicates. Uses underlying `dropDuplicates` construct. </li><li>First: Keeps first occurrence of the duplicate row. </li><li>Last: Keeps last occurrence of the duplicate row.</li><li>Unique Only: Keeps rows that don't have duplicates. </li><li>Distinct Rows: Keeps all distinct rows. This is equivalent to performing a `df.distinct()` operation.</li></ul> |
| Deduplicate columns | Columns to consider while removing duplicate rows (not required for `Distinct Rows`)                                                                                                                                                                                                                                                                                                                                |
| Order columns       | Columns to sort DataFrame on before de-duping in case of `First` and `Last` rows to keep. Sorting options: <ul><li>Ascending: Sort values in ascending order.</li><li>Descending: Sort values in descending order.</li><li>Nulls first: Place null values at the beginning of the sorted result.</li><li>Nulls last: Place null values at the end of the sorted result.</li></ul>                                   |

## Examples

### Rows to keep: `Any`

<img src="https://mintcdn.com/prophecy-62973bd0/YMU5yAViYYX3rOGW/data-engineering/gems/transform/img/deduplicate_eg_1.png?fit=max&auto=format&n=YMU5yAViYYX3rOGW&q=85&s=f62af5ef6d7f6fd72b258b4fa975e0de" alt="Example usage of Deduplicate" width="940" height="283" data-path="data-engineering/gems/transform/img/deduplicate_eg_1.png" />

<CodeGroup>
  ```python example.py theme={null}
  def dedup(spark: SparkSession, in0: DataFrame) -> DataFrame:
   return in0.dropDuplicates(["tran_id"])
  ```

  ```scala example.scala theme={null}
  object dedup {
   def apply(spark: SparkSession, in: DataFrame): DataFrame = {
   in.dropDuplicates(List("tran_id"))
   }
  }
  ```
</CodeGroup>

***

### Rows to keep: `First`

<img src="https://mintcdn.com/prophecy-62973bd0/YMU5yAViYYX3rOGW/data-engineering/gems/transform/img/dedup_eg_first.png?fit=max&auto=format&n=YMU5yAViYYX3rOGW&q=85&s=31b086c5398152041c8bfa046b77cf10" alt="Example usage of Deduplicate - First" width="2000" height="845" data-path="data-engineering/gems/transform/img/dedup_eg_first.png" />

<CodeGroup>
  ```python example.py theme={null}
  def earliest_cust_order(spark: SparkSession, in0: DataFrame) -> DataFrame:
   return in0\
   .withColumn(
   "row_number",
   row_number()\
   .over(Window\
   .partitionBy("customer_id")\
   .orderBy(col("order_dt").asc())
   )\
   .filter(col("row_number") == lit(1))\
   .drop("row_number")
  ```

  ```scala example.scala theme={null}
  object earliest_cust_order {
   def apply(spark: SparkSession, in: DataFrame): DataFrame = {
   import org.apache.spark.sql.expressions.Window
   in.withColumn(
   "row_number",
   row_number().over(
   Window
   .partitionBy("customer_id")
   .orderBy(col("order_date").asc)
   )
   )
   .filter(col("row_number") === lit(1))
   .drop("row_number")
   }
  }
  ```
</CodeGroup>

***

### Rows to keep: `Last`

<img src="https://mintcdn.com/prophecy-62973bd0/YMU5yAViYYX3rOGW/data-engineering/gems/transform/img/dedup_eg_last.png?fit=max&auto=format&n=YMU5yAViYYX3rOGW&q=85&s=b9d2a13d0287d877a5dc696664cc8ea2" alt="Example usage of Deduplicate - Last" width="3974" height="1678" data-path="data-engineering/gems/transform/img/dedup_eg_last.png" />

<CodeGroup>
  ```python example.py theme={null}
  def latest_cust_order(spark: SparkSession, in0: DataFrame) -> DataFrame:
   return in0\
   .withColumn(
   "row_number",
   row_number()\
   .over(Window\
   .partitionBy("customer_id")\
   .orderBy(col("order_dt").asc())
   )\
   .withColumn(
   "count",
   count("*")\
   .over(Window\
   .partitionBy("customer_id")
   )\
   .filter(col("row_number") == col("count"))\
   .drop("row_number")\
   .drop("count")
  ```

  ```scala example.scala theme={null}
  object latest_cust_order {
   def apply(spark: SparkSession, in: DataFrame): DataFrame = {
   import org.apache.spark.sql.expressions.Window
   in.withColumn(
   "row_number",
   row_number().over(
   Window
   .partitionBy("customer_id")
   .orderBy(col("order_date").asc)
   )
   )
   .withColumn(
   "count",
   count("*").over(
   Window
   .partitionBy("customer_id")
   )
   )
   .filter(col("row_number") === col("count"))
   .drop("row_number")
   .drop("count")
   }
  }
  ```
</CodeGroup>

### Rows to keep: `Unique Only`

<img src="https://mintcdn.com/prophecy-62973bd0/YMU5yAViYYX3rOGW/data-engineering/gems/transform/img/dedup_eg_unique.png?fit=max&auto=format&n=YMU5yAViYYX3rOGW&q=85&s=8fd3bf3ab66956cb8251294a33018484" alt="Example usage of Deduplicate - Unique" width="1906" height="809" data-path="data-engineering/gems/transform/img/dedup_eg_unique.png" />

<CodeGroup>
  ```python example.py theme={null}
  def single_order_customers(spark: SparkSession, in0: DataFrame) -> DataFrame:
   return in0\
   .withColumn(
   "count",
   count("*")\
   .over(Window\
   .partitionBy("customer_id")
   )\
   .filter(col("count") == lit(1))\
   .drop("count")
  ```

  ```scala example.scala theme={null}
  object single_order_customers {
   def apply(spark: SparkSession, in: DataFrame): DataFrame = {
   import org.apache.spark.sql.expressions.Window
   in.withColumn(
   "count",
   count("*").over(
   Window
   .partitionBy("customer_id")
   )
   )
   .filter(col("count") === lit(1))
   .drop("count")
   }

  }
  ```
</CodeGroup>

### Rows to keep: `Distinct Rows`

<img src="https://mintcdn.com/prophecy-62973bd0/YMU5yAViYYX3rOGW/data-engineering/gems/transform/img/dedup_eg_distinct.png?fit=max&auto=format&n=YMU5yAViYYX3rOGW&q=85&s=e9d398b2eacb841837f910cbaffbd755" alt="Example usage of Deduplicate - Distinct" width="2042" height="846" data-path="data-engineering/gems/transform/img/dedup_eg_distinct.png" />

<CodeGroup>
  ```python example.py theme={null}
  def single_order_customers(spark: SparkSession, in0: DataFrame) -> DataFrame:
   return in0.distinct()
  ```

  ```scala example.scala theme={null}
  object single_order_customers {
   def apply(spark: SparkSession, in: DataFrame): DataFrame = {
   in.distinct()
   }

  }
  ```
</CodeGroup>
