我在这里发布的问题与我的相似,但在尝试一些已接受的答案时,我的代码仍然出现错误。我有一个包含三列的数据框 - 创建_at,text和words(这只是文本的标记化版本)。见下文:
现在,我有一个公司列表['Starbucks', 'Nvidia', 'IBM', 'Dell']
,我只想保留文本中包含上述字词的行。
我尝试了一些事情,但没有成功:
small_DF.filter(lambda x: any(word in x.text for word in test_list))
返回:TypeError:condition应为string或Column
我尝试创建一个函数并使用foreach()
:
def filters(line):
return(any(word in line for word in test_list))
df = df.foreach(filters)
将df变为'Nonetype'
我试过的最后一个:
df = df.filter((col("text").isin(test_list))
这会返回一个空数据帧,这很好,因为我没有错误,但显然不是我想要的。
答案 0 :(得分:1)
我认为filter
不起作用,因为它期望lambda函数的布尔输出和isin
只与列进行比较。您正在尝试将单词列表与单词列表进行比较。我试过的东西可以给你一些方向 -
# prepare some test data ==>
words = [x.lower() for x in ['starbucks', 'Nvidia', 'IBM', 'Dell']]
data = [['i love Starbucks'],['dell laptops rocks'],['help me I am stuck!']]
df = spark.createDataFrame(data).toDF('text')
from pyspark.sql.types import *
def intersect(row):
# convert each word in lowecase
row = [x.lower() for x in row.split()]
return True if set(row).intersection(set(words)) else False
filterUDF = udf(intersect,BooleanType())
df.where(filterUDF(df.text)).show()
输出:
+------------------+
| text|
+------------------+
| i love Starbucks|
|dell laptops rocks|
+------------------+
答案 1 :(得分:1)
您的.filter
会返回错误,因为它是数据帧上的sql过滤器函数(期望BooleanType()
列)而不是RDD上的过滤器函数。如果您想使用RDD,只需添加.rdd
:
small_DF.rdd.filter(lambda x: any(word in x.text for word in test_list))
您不必使用UDF,您可以在列.rlike
上使用"text"
的pyspark中使用正则表达式:
from pyspark.sql import HiveContext
hc = HiveContext(sc)
import pyspark.sql.functions as psf
words = [x.lower() for x in ['starbucks', 'Nvidia', 'IBM', 'Dell']]
data = [['i love Starbucks'],['dell laptops rocks'],['help me I am stuck!']]
df = hc.createDataFrame(data).toDF('text')
df.filter(psf.lower(df.text).rlike('|'.join(words)))