Pertanyaan Memfilter DataFrame menggunakan panjang kolom


Saya ingin memfilter DataFrame menggunakan kondisi yang terkait dengan panjang kolom, pertanyaan ini mungkin sangat mudah tetapi saya tidak menemukan pertanyaan terkait di SO.

Lebih spesifik, saya punya DataFrame hanya dengan satu Column yang mana dari ArrayType(StringType()), Saya ingin menyaring DataFrame menggunakan panjang sebagai penyaring, saya mengambil cuplikan di bawah ini.

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.

saya membaca Dokumentasi Kolom, tetapi tidak menemukan properti apa pun yang berguna untuk masalah ini. Saya menghargai bantuan apa pun!


22
2017-11-13 14:49


asal


Jawaban:


Di Spark> = 1,5 Anda dapat menggunakan size fungsi:

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

Di Spark <1.5 UDF harus melakukan trik:

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

Jika Anda menggunakan HiveContext kemudian size UDF dengan SQL mentah harus bekerja dengan versi apa pun:

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

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

Untuk kolom string Anda bisa menggunakan udf didefinisikan di atas atau length fungsi:

from pyspark.sql.functions import length

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

## +---+
## |  k|
## +---+
## |bar|
## +---+

42
2017-11-13 15:02