【问题标题】:Show distinct column values in pyspark dataframe在 pyspark 数据框中显示不同的列值
【发布时间】:2017-01-15 22:49:09
【问题描述】:

使用 pyspark 数据框,你如何做到相当于 Pandas df['col'].unique()

我想列出 pyspark 数据框列中的所有唯一值。

不是 SQL 类型的方式(registertemplate 然后 SQL 查询不同的值)。

我也不需要groupby 然后countDistinct,而是想检查该列中的不同值。

【问题讨论】:

    标签: python apache-spark pyspark apache-spark-sql


    【解决方案1】:

    这应该有助于获取列的不同值:

    df.select('column1').distinct().collect()
    

    请注意,.collect() 对可以返回的值的数量没有任何内置限制,因此这可能会很慢 - 请改用.show() 或在.collect() 之前添加.limit(20) 来管理它。

    【讨论】:

    • 此代码返回不可迭代的数据,即我看到不同的数据位无法在代码中对其进行迭代。任何其他使我能够做到的方式。我尝试使用 toPandas() 将其转换为 Pandas df,然后获取具有唯一值的迭代。但是,遇到“找不到 Pandas”错误消息
    • @Abhi: 代替 .show() 代替执行 .collect(),这样您将获得该特定列的所有不同值的可迭代。但是请确保您的主节点有足够的内存来保存这些唯一值,因为 collect 会将所有请求的数据(在这种情况下为列的唯一值)推送到主节点:)
    • @Satya 我已将您的评论编辑为答案,谢谢
    • 要获得 Python 实际值列表 而不是 Row 对象,您需要使用类似以下答案的列表理解:stackoverflow.com/a/60896261/7465462
    【解决方案2】:

    假设我们正在使用以下数据表示形式(两列,kv,其中 k 包含三个条目,两个唯一的:

    +---+---+
    |  k|  v|
    +---+---+
    |foo|  1|
    |bar|  2|
    |foo|  3|
    +---+---+
    

    使用 Pandas 数据框:

    import pandas as pd
    p_df = pd.DataFrame([("foo", 1), ("bar", 2), ("foo", 3)], columns=("k", "v"))
    p_df['k'].unique()
    

    这会返回一个ndarray,即array(['foo', 'bar'], dtype=object)

    您要求提供“pandas df['col'].unique() 的 pyspark 数据框替代方案”。现在,给定以下 Spark 数据帧:

    s_df = sqlContext.createDataFrame([("foo", 1), ("bar", 2), ("foo", 3)], ('k', 'v'))
    

    如果您希望 Spark 的结果相同,即ndarray,请使用toPandas()

    s_df.toPandas()['k'].unique()
    

    或者,如果您不需要专门的 ndarray 并且只想要列 k 的唯一值的列表:

    s_df.select('k').distinct().rdd.map(lambda r: r[0]).collect()
    

    最后,您还可以使用列表推导式,如下所示:

    [i.k for i in s_df.select('k').distinct().collect()]
    

    【讨论】:

    • 嗨 eddies,最后一行代码 distinct().map() 对我不起作用。错误:AttributeError:“DataFrame”对象没有属性“map”。我正在使用火花 2.0。还有 toPandas 的东西,我不会说它是替代品,它先将 spark 数据帧转换为 pandas 数据帧,然后对其进行 pandas 操作。
    • 嗨,萨蒂亚。刚刚通过在distinct() 之后添加.rdd 调用来更新答案。它在 Spark 1.6.2 中没有这个功能,但我刚刚确认编辑后的答案也适用于 Spark 2.0.0。
    • 为什么要尝试通过转换为 pandas 数据帧(如果它很大会受伤)或在 spark 数据帧完全能够做到这一点时使用 rdd 操作来避免 spark 数据帧操作?见下面@Pabbati 的回答
    • @Laurens 上面的答案有三个解决方案,具体取决于发布者真正想要的。在所有情况下,张贴者都想要某种形式的不同值的列表/数组(参见张贴者对 seufagner 的回答的回应)。上面的第三个解决方案确实使用了 Spark 的数据框 api,就像 Pabbati 的回答一样,但实际上返回了一个列表,根据发布者的要求。
    • 是的,问题标题中包含“show”一词。但发帖人特别澄清说,看到结果是不够的,并想要一份清单。如上所述,请参阅发布者对 seufagner 答案的评论。
    【解决方案3】:

    您可以使用df.dropDuplicates(['col1','col2']) 仅根据数组中的 colX 获取不同的行。

    【讨论】:

    • @seufagner-yes 我可以执行 df.dropDuplictes(['col1']) 来查看(标记 SEE )唯一值,但没有 collect(to_rdd 或 to pandas DF 然后 df[' col'].unique()),我无法获得唯一值列表。感谢您的建议。
    • 用户没有询问如何显示非重复值。他只是想获取所有唯一/不同项目的列表,其中也包括重复项!
    【解决方案4】:

    如果您想查看数据框中特定列的不同值,您只需编写以下代码。它将显示df 数据框中colname 列的100 个不同值(如果有100 个值可用)。

    df.select('colname').distinct().show(100, False)
    

    如果你想对不同的值做一些花哨的事情,你可以将不同的值保存在一个向量中:

    a = df.select('colname').distinct()
    

    【讨论】:

      【解决方案5】:

      collect_set 可以帮助从 pyspark.sql.DataFrame 的给定列中获取唯一值 df.select(F.collect_set("column").alias("column")).first()["column"]

      【讨论】:

        【解决方案6】:

        你可以这样做

        distinct_column = 'somecol' 
        
        distinct_column_vals = df.select(distinct_column).distinct().collect()
        distinct_column_vals = [v[distinct_column] for v in distinct_column_vals]
        

        【讨论】:

          【解决方案7】:

          除了dropDuplicates 选项之外,还有我们在pandas drop_duplicates 中命名的方法:

          drop_duplicates()dropDuplicates() 的别名。

          示例

          s_df = sqlContext.createDataFrame([("foo", 1),
                                             ("foo", 1),
                                             ("bar", 2),
                                             ("foo", 3)], ('k', 'v'))
          s_df.show()
          
          +---+---+
          |  k|  v|
          +---+---+
          |foo|  1|
          |foo|  1|
          |bar|  2|
          |foo|  3|
          +---+---+
          

          按子集删除

          s_df.drop_duplicates(subset = ['k']).show()
          
          +---+---+
          |  k|  v|
          +---+---+
          |bar|  2|
          |foo|  1|
          +---+---+
          s_df.drop_duplicates().show()
          
          
          +---+---+
          |  k|  v|
          +---+---+
          |bar|  2|
          |foo|  3|
          |foo|  1|
          +---+---+
          

          【讨论】:

            【解决方案8】:

            先运行这个

            df.createOrReplaceTempView('df')
            

            然后运行

            spark.sql("""
                SELECT distinct
                    column name
                FROM
                    df
                """).show()
            

            【讨论】:

              【解决方案9】:

              如果您想选择与 DataFrame (df) 不同的所有(列)数据,那么

              df.select('*').distinct().show(10,truncate=False)

              【讨论】:

                【解决方案10】:

                假设您的原始 DataFrame 名为 df。然后,您可以使用:

                df1 = df.groupBy('column_1').agg(F.count('column_1').alias('trip_count'))
                df2 = df1.sort(df1.trip_count.desc()).show()
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2020-09-02
                  • 1970-01-01
                  • 2021-01-16
                  • 2017-01-02
                  • 1970-01-01
                  • 2014-04-28
                  • 2019-03-21
                  • 1970-01-01
                  相关资源
                  最近更新 更多