mostrar valores de columna distintos en el marco de datos pyspark: python

82

Sugiera una alternativa de marco de datos pyspark para Pandas df['col'].unique().

Quiero enumerar todos los valores únicos en una columna de marco de datos pyspark.

No es la forma de tipo SQL (registertemplate y luego consulta SQL para valores distintos).

Además, no lo necesito groupby->countDistinct, en cambio, quiero verificar distintos VALORES en esa columna.

Satya
fuente

Respuestas:

84

Supongamos que estamos trabajando con la siguiente representación de datos (dos columnas ky v, donde kcontiene tres entradas, dos únicas:

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

Con un marco de datos de Pandas:

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

Esto devuelve un ndarray, es decirarray(['foo', 'bar'], dtype=object)

Solicitó una "alternativa de marco de datos pyspark para pandas df ['col']. Unique ()". Ahora, dado el siguiente marco de datos de Spark:

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

Si desea el mismo resultado de Spark, es decir ndarray, use toPandas():

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

Alternativamente, si no necesita ndarrayespecíficamente y solo desea una lista de los valores únicos de la columna k:

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

Finalmente, también puede usar una lista de comprensión de la siguiente manera:

[i.k for i in s_df.select('k').distinct().collect()]
remolinos
fuente
1
Hola remolinos, la última línea de código distinta (). Map () no funcionó para mí. Error: AttributeError: el objeto 'DataFrame' no tiene ningún atributo 'map'. Estoy en Spark 2.0. Y para Pandas, no diré que sea una alternativa, primero convierte el marco de datos de Spark en el marco de datos de Pandas y luego realiza la operación de pandas en él.
Satya
1
Hola satya. Acabo de actualizar la respuesta agregando una .rddllamada después distinct(). Funcionó sin eso en Spark 1.6.2, pero acabo de confirmar que la respuesta editada también funciona en Spark 2.0.0.
remolinos
4
¿Por qué intentar evitar las operaciones de tramas de datos de chispa convirtiéndolas en una trama de datos de pandas (duele si es gigantesca) o utilizando operaciones rdd cuando las tramas de datos de chispa son perfectamente capaces de hacer esto? ver a continuación la respuesta de @Pabbati
Laurens Koppenol
@Laurens Hubo tres soluciones en la respuesta anterior, dependiendo de lo que realmente quisiera el póster. En todos los casos, el cartel quería algún tipo de lista / matriz de los valores distintos (véase la respuesta del cartel a la respuesta de seufagner). La tercera solución anterior usa la API de marco de datos de Spark tal como la respuesta de Pabbati, pero en realidad devuelve una lista, según los requisitos del póster.
remolinos el
1
Sí, el título de la pregunta incluye la palabra "mostrar". Pero el cartel aclaró específicamente que VER los resultados no era adecuado y quería una lista. Como se mencionó anteriormente, vea el comentario del cartel a la respuesta de seufagner.
remolinos
198

Esto debería ayudar a obtener valores distintos de una columna:

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

Tenga en cuenta que .collect()no tiene ningún límite incorporado sobre la cantidad de valores que pueden devolver, por lo que esto podría ser lento; use .show()en su lugar o agregue .limit(20)antes .collect()para administrar esto.

Pabbati
fuente
este código devuelve datos que no son iterables, es decir, veo que el bit de datos distintos no puedo iterar sobre él en el código. Cualquier otra forma que me permita hacerlo. Intenté usar toPandas () para convertirlo en Pandas df y luego obtener el iterable con valores únicos. Sin embargo, aparece el mensaje de error `` Pandas no encontrados ''
Abhi
6
@Abhi: en lugar de .show () en lugar de hacer un .collect (), de esa manera obtendrá un iterable de todos los valores distintos de esa columna en particular. Pero asegúrese de que su nodo maestro tenga suficiente memoria para mantener esos valores únicos, porque recopilar enviará todos los datos solicitados (en este caso, valores únicos de la columna) al nodo maestro :)
Satya
1
@Satya He editado tu comentario en la respuesta, gracias
MichaelChirico
14

Puede usar df.dropDuplicates(['col1','col2'])para obtener solo filas distintas basadas en colX en la matriz.

seufagner
fuente
2
@ seufagner-yes Puedo hacer un df.dropDuplictes (['col1']) para ver (marque SEE) los valores únicos, pero sin una recopilación (to_rdd o pandas DF y luego df ['col']. unique ()) , No puedo obtener la lista de valores únicos. Gracias por la sugerencia.
Sábado
El usuario no preguntó cómo mostrar valores no duplicados. ¡Solo quería obtener una lista de todos los elementos únicos / distintos, que también incluye duplicados!
Utsav Jha
6

collect_set puede ayudar a obtener valores únicos de una columna determinada de pyspark.sql.DataFrame df.select(F.collect_set("column").alias("column")).first()["column"]

Hari Baskar
fuente
1

Si desea seleccionar TODOS los datos (columnas) como distintos de un DataFrame (df), entonces

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

Kapil Sharma
fuente
1

Podrías hacerlo

distinct_column = 'somecol' 

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

Además de la dropDuplicatesopción, existe el método denominado como lo conocemos en :pandas drop_duplicates

drop_duplicates () es un alias de dropDuplicates () .

Ejemplo

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|
+---+---+

Gota por subconjunto

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|
+---+---+
ansev
fuente
0

Ejecuta esto primero

df.createOrReplaceTempView('df')

Entonces corre

spark.sql("""
    SELECT distinct
        column name
    FROM
        df
    """).show()
José Jacob
fuente
0

Si desea ver los valores distintos de una columna específica en su marco de datos, solo necesitaría escribir:

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

Esto mostraría los 100 valores distintos (si hay 100 valores disponibles) para la columna colname en el marco de datos df.

Si desea hacer algo elegante con los valores distintos, puede guardar los valores distintos en un vector

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

Aquí, a tendría todos los valores distintos de la columna colname

Nidhi
fuente