簡體   English   中英

pyspark:獲取列表值的不同元素

[英]pyspark: get the distinct elements of list values

我有一個這種形式的 rdd,

rdd = sc.parallelize([('A', [1, 2, 4, 1, 2, 5]), ('B', [2, 3, 2, 1, 5, 10]), ('C', [3, 2, 5, 10, 5, 2])])

但我想像下面那樣轉換 rdd,

newrdd = [('A', [1, 2, 4, 5]), ('B', [2, 3, 1, 5, 10], ('C', [3, 2, 5, 10])]

意思是,我必須獲得不同的價值觀元素。 ReduceByKey()在這里沒有幫助。

我怎樣才能做到這一點?

從 Spark 2.4 開始,您可以使用 PySpark SQL 函數array_distinct

df = rdd.toDF(("category", "values"))
df.withColumn("foo", array_distinct(col("values"))).show()
+--------+-------------------+----------------+
|category|             values|             foo|
+--------+-------------------+----------------+
|       A| [1, 2, 4, 1, 2, 5]|    [1, 2, 4, 5]|
|       B|[2, 3, 2, 1, 5, 10]|[2, 3, 1, 5, 10]|
|       C|[3, 2, 5, 10, 5, 2]|   [3, 2, 5, 10]|
+--------+-------------------+----------------+

它的優點是不將 JVM 對象轉換為 Python 對象,因此比任何 Python UDF 都更有效。 但是,它是一個 DataFrame 函數,因此您必須將 RDD 轉換為 DataFrame。 大多數情況下也建議這樣做。

這是在 Python 中獲取結果的直接方法。 請注意,RDD 是不可變的。

設置 Spark 會話/上下文

from pyspark.sql import SparkSession
from pyspark import SparkContext

spark = SparkSession.builder \
            .master("local") \
            .appName("SO Solution") \
            .getOrCreate()

sc = spark.sparkContext

解決方案代碼

rdd = sc.parallelize([('A', [1, 2, 4, 1, 2, 5]), ('B', [2, 3, 2, 1, 5, 10]), ('C', [3, 2, 5, 10, 5, 2])])

newrdd = rdd.map(lambda x : (x[0], list(set(x[1]))))

newrdd.collect()

輸出

[('A', [1, 2, 4, 5]), ('B', [1, 2, 3, 5, 10]), ('C', [10, 2, 3, 5])]

您可以將數組轉換為 set 以獲得不同的值。 這是如何 - 我已經稍微改變了語法以使用 scala。

    val spark : SparkSession = SparkSession.builder
      .appName("Test")
      .master("local[2]")
      .getOrCreate()
    import spark.implicits._
    val df = spark.createDataset(List(("A", Array(1, 2, 4, 1, 2, 5)), ("B", Array(2, 3, 2, 1, 5, 10)), ("C", Array(3, 2, 5, 10, 5, 2))))
    df.show()

    val dfDistinct = df.map(r=> (r._1, r._2.toSet) )
    dfDistinct.show()
old_rdd = [('A', [1, 2, 4, 1, 2, 5]), ('B', [2, 3, 2, 1, 5, 10]), ('C', [3, 2, 5, 10, 5, 2])]
new_rdd = [(letter, set(numbers)) for letter, numbers in old_rdd]

像這樣?

或者list(set(numbers))如果你真的需要它們成為一個列表?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM