在pyspark数据框中显示不同的列值:python


81

请为Pandas建议pyspark数据框替代方案df['col'].unique()

我想在pyspark dataframe列中列出所有唯一值。

不是SQL类型的方式(先注册模板,然后通过SQL查询不同的值)。

另外,我不需要groupby->countDistinct,相反,我想检查该列中的不同值。

Answers:


83

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

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

使用熊猫数据框:

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)

您要求提供“用于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专门的列,而只需要column的唯一值的列表k

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

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

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

1
嗨,漩涡,最后的代码行distinct()。map()对我不起作用。错误:AttributeError:“ DataFrame”对象没有属性“ map”。我正在使用Spark 2.0。至于toPandas的事情,我不会说这是另一种选择,它先将spark数据帧转换为pandas数据帧,然后对其进行pandas操作。
萨蒂亚

1
嗨,萨蒂亚。刚刚通过添加一个.rdd呼叫来更新答案distinct()。它在Spark 1.6.2中没有此功能,但我只是确认编辑后的答案在Spark 2.0.0中也适用。
涡流

4
当Spark数据帧完全有能力做到这一点时,为什么要尝试通过转换为Pandas数据帧(如果巨大的话会损坏)或利用rdd操作来避免spark数据帧操作呢?参见@Pabbati的以下答案
Laurens Koppenol

@Laurens上面的答案中有三种解决方案,具体取决于发布者的实际需求。在所有情况下,发布者都需要某种形式的独特值列表/数组(请参见发布者对seufagner回答的回应)。上面的第三个解决方案确实使用Spark的dataframe api作为Pabbati的答案,但实际上根据发帖人的要求返回了一个列表。
漩涡

1
是的,问题标题包括单词“ show”。但是发帖人明确指出,查看结果还不够,需要一个清单。如上所述,请参见海报对seufagner的回答。
eddies

198

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

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

请注意,.collect()返回的值没有内置的限制,因此这可能很慢-.show()改用或先添加.limit(20)后再.collect()进行管理。


此代码返回不可迭代的数据,即,我看到不同的数据位无法在代码中对其进行迭代。使我能够执行此操作的任何其他方法。我尝试使用toPandas()将其转换为Pandas df,然后使用唯一值进行迭代。但是,遇到“找不到熊猫”错误消息
Abhi

6
@Abhi:代替.show()而是执行.collect(),那样您将获得该特定列的所有不同值的可迭代值。但是请确保您的主节点有足够的内存来保留这些唯一值,因为collect会将所有请求的数据(在本例中为列的唯一值)推送到主节点:)
Satya

1
@Satya我已将您的评论编辑成答案,谢谢
MichaelChirico

14

您可以df.dropDuplicates(['col1','col2'])用来仅基于数组中的colX获得不同的行。


2
@seufagner是,我可以执行df.dropDuplictes(['col1'])来查看(标记为SEE)唯一值,但是没有collect(to_rdd或熊猫DF,然后是df ['col']。unique()) ,我无法获得唯一值列表。感谢您的建议。
萨蒂亚

用户没有询问如何显示非重复值。.他只是想获得所有唯一/不同项目的列表,其中也包括重复项!
Utsav Jha



1

你可以做

distinct_column = 'somecol' 

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

0

除了该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|
+---+---+

0

首先运行

df.createOrReplaceTempView('df')

然后跑

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

0

如果您想查看数据框中特定列的不同值,则只需编写-

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

这将显示df数据框中colname列的100个不同值(如果有100个值可用)。

如果您想对不同的值进行某些处理,可以将不同的值保存在向量中

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

在这里,a将具有列colname的所有不同值

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.