Filtrado de DataFrame usando la longitud de una columna

Quiero filtrar un DataFrame usando una condición relacionada con la longitud de una columna, esta pregunta puede ser muy fácil pero no encontré ninguna pregunta relacionada en el SO.

Más específicamente, tengo un DataFrame con solo una Column que de ArrayType(StringType()) , quiero filtrar el DataFrame usando la longitud como filtro, tiro un fragmento a continuación.

 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. 

Leí la documentación de la columna , pero no encontré ninguna propiedad útil para este asunto. ¡Aprecio cualquier ayuda!

En Spark> = 1.5 puedes usar la función de size :

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

En Spark <1.5, un UDF debería hacer el truco:

 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 usa HiveContext , el size UDF con SQL sin size debería funcionar con cualquier versión:

 df.registerTempTable("df") sqlContext.sql("SELECT * FROM df WHERE size(tokens) <= 3").show() ## +--------------------+ ## | tokens| ## +--------------------+ ## |ArrayBuffer(S, U, S)| ## +--------------------+ 

Para las columnas de cadena, puede usar una función udf definida anteriormente o length :

 from pyspark.sql.functions import length df = sqlContext.createDataFrame([("fooo", ), ("bar", )], ("k", )) df.where(length(col("k")) <= 3).show() ## +---+ ## | k| ## +---+ ## |bar| ## +---+ 

Aquí hay un ejemplo para String en scala:

 val stringData = Seq(("Maheswara"), ("Mokshith")) val df = sc.parallelize(stringData).toDF df.where((length($"value")) <= 8).show +--------+ | value| +--------+ |Mokshith| +--------+ df.withColumn("length", length($"value")).show +---------+------+ | value|length| +---------+------+ |Maheswara| 9| | Mokshith| 8| +---------+------+ 

@AlbertoBonsanto: debajo de los filtros de código según el tamaño de la matriz:

 val input = Seq(("a1,a2,a3,a4,a5"), ("a1,a2,a3,a4"), ("a1,a2,a3"), ("a1,a2"), ("a1")) val df = sc.parallelize(input).toDF("tokens") val tokensArrayDf = df.withColumn("tokens", split($"tokens", ",")) tokensArrayDf.show +--------------------+ | tokens| +--------------------+ |[a1, a2, a3, a4, a5]| | [a1, a2, a3, a4]| | [a1, a2, a3]| | [a1, a2]| | [a1]| +--------------------+ tokensArrayDf.filter(size($"tokens") > 3).show +--------------------+ | tokens| +--------------------+ |[a1, a2, a3, a4, a5]| | [a1, a2, a3, a4]| +--------------------+