Filtrage de DataFrame en utilisant la longueur d'une colonne

je veux filtre DataFrame en utilisant une condition liée à la longueur d'une colonne, cette question pourrait être très facile, mais je n'ai pas trouvé de question liée dans le SO.

plus précisément, j'ai un DataFrame avec un seul ColumnArrayType(StringType()), je veux filtrer les DataFrame en utilisant la longueur comme filtreur, j'ai tiré un extrait ci-dessous.

df = sqlContext.read.parquet("letters.parquet")
df.show()

# The output will be 
# +------------+
# |      tokens|
# +------------+
# |[L, S, Y, S]|
# |[L, V, I, S]|
# |[I, A, N, A]|
# |[I, L, S, A]|
# |[E, N, N, Y]|
# |[E, I, M, A]|
# |[O, A, N, A]|
# |   [S, U, S]|
# +------------+

# But I want only the entries with length 3 or less
fdf = df.filter(len(df.tokens) <= 3)
fdf.show() # But it says that the TypeError: object of type 'Column' has no len(), so the previous statement is obviously incorrect.

j'ai lu documentation de la colonne, mais n'a trouvé aucune propriété utile à cet égard. J'apprécie tout à l'aide!

23
demandé sur Community 2015-11-13 17:49:08

1 réponses

dans Spark > = 1.5 vous pouvez utiliser size fonction:

from pyspark.sql.functions import col, size

df = sqlContext.createDataFrame([
    (["L", "S", "Y", "S"],  ),
    (["L", "V", "I", "S"],  ),
    (["I", "A", "N", "A"],  ),
    (["I", "L", "S", "A"],  ),
    (["E", "N", "N", "Y"],  ),
    (["E", "I", "M", "A"],  ),
    (["O", "A", "N", "A"],  ),
    (["S", "U", "S"],  )], 
    ("tokens", ))

df.where(size(col("tokens")) <= 3).show()

## +---------+
## |   tokens|
## +---------+
## |[S, U, S]|
## +---------+

Spark < 1.5 UDF devrait faire l'affaire:

from pyspark.sql.types import IntegerType
from pyspark.sql.functions import udf

size_ = udf(lambda xs: len(xs), IntegerType())

df.where(size_(col("tokens")) <= 3).show()

## +---------+
## |   tokens|
## +---------+
## |[S, U, S]|
## +---------+

Si vous utilisez HiveContextsize UDF avec raw SQL devrait fonctionner avec n'importe quelle version:

df.registerTempTable("df")
sqlContext.sql("SELECT * FROM df WHERE size(tokens) <= 3").show()

## +--------------------+
## |              tokens|
## +--------------------+
## |ArrayBuffer(S, U, S)|
## +--------------------+

pour les colonnes string vous pouvez utiliser un udf défini ci-dessus ou length fonction:

from pyspark.sql.functions import length

df = sqlContext.createDataFrame([("fooo", ), ("bar", )], ("k", ))
df.where(length(col("k")) <= 3).show()

## +---+
## |  k|
## +---+
## |bar|
## +---+
45
répondu zero323 2017-11-08 22:02:01