Python 基于广播变量的pyspark滤波器数据帧

Python 基于广播变量的pyspark滤波器数据帧,python,pyspark,broadcast,Python,Pyspark,Broadcast,我有一个pyspark 2.0数据帧,我正试图根据一个(相对)短的列表进行过滤——可能长度为50-100 filterList = ['A','B','C'] 我希望将该列表广播到我的每个节点,并使用它删除两列之一不在列表中的记录 此操作的工作原理是: filter_df= df.where((df['Foo'].isin(filterList )) | (df['Bar'].isin(filterList))) 但是,当我广播列表时,我得到了一个错误: filterListB= sc.br

我有一个pyspark 2.0数据帧,我正试图根据一个(相对)短的列表进行过滤——可能长度为50-100

filterList = ['A','B','C']
我希望将该列表广播到我的每个节点,并使用它删除两列之一不在列表中的记录

此操作的工作原理是:

filter_df= df.where((df['Foo'].isin(filterList )) | (df['Bar'].isin(filterList)))
但是,当我广播列表时,我得到了一个错误:

filterListB= sc.broadcast(filterList)

filter_df= df.where((df['Foo'].isin(filterListB)) | (df['Bar'].isin(filterListB)))

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-99-1b972cf29148> in <module>()
----> 1 filter_df= df.where((df['Foo'].isin(filterListB)) | (df['Bar'].isin(filterListB)))

/usr/local/spark/python/pyspark/sql/column.pyc in isin(self, *cols)
    284         if len(cols) == 1 and isinstance(cols[0], (list, set)):
    285             cols = cols[0]
--> 286         cols = [c._jc if isinstance(c, Column) else _create_column_from_literal(c) for c in cols]
    287         sc = SparkContext._active_spark_context
    288         jc = getattr(self._jc, "isin")(_to_seq(sc, cols))

/usr/local/spark/python/pyspark/sql/column.pyc in _create_column_from_literal(literal)
     33 def _create_column_from_literal(literal):
     34     sc = SparkContext._active_spark_context
---> 35     return sc._jvm.functions.lit(literal)
     36 
     37 

/usr/local/spark/python/lib/py4j-0.10.3-src.zip/py4j/java_gateway.py in __call__(self, *args)
   1122 
   1123     def __call__(self, *args):
-> 1124         args_command, temp_args = self._build_args(*args)
   1125 
   1126         command = proto.CALL_COMMAND_NAME +\

/usr/local/spark/python/lib/py4j-0.10.3-src.zip/py4j/java_gateway.py in _build_args(self, *args)
   1092 
   1093         args_command = "".join(
-> 1094             [get_command_part(arg, self.pool) for arg in new_args])
   1095 
   1096         return args_command, temp_args

/usr/local/spark/python/lib/py4j-0.10.3-src.zip/py4j/protocol.py in get_command_part(parameter, python_proxy_pool)
    287             command_part += ";" + interface
    288     else:
--> 289         command_part = REFERENCE_TYPE + parameter._get_object_id()
    290 
    291     command_part += "\n"

AttributeError: 'Broadcast' object has no attribute '_get_object_id'
filterListB=sc.broadcast(过滤器列表)
filter_df=df.where((df['Foo'].isin(filterListB))|(df['Bar'].isin(filterListB)))
---------------------------------------------------------------------------
AttributeError回溯(最近一次呼叫上次)
在()
---->1 filter_df=df.where((df['Foo'].isin(filterListB))|(df['Bar'].isin(filterListB)))
/isin中的usr/local/spark/python/pyspark/sql/column.pyc(self,*cols)
284如果len(cols)=1且isinstance(cols[0],(列表,设置)):
285列=列[0]
-->286 cols=[c._jcif isinstance(c,Column)else _create_Column_from_literal(c)for c in cols]
287 sc=SparkContext.\u活动\u spark\u上下文
288 jc=getattr(self._jc,“isin”)(_to_seq(sc,cols))
/usr/local/spark/python/pyspark/sql/column.pyc在_create_column_from_literal(literal)中
33定义从文字创建列文字(文字):
34 sc=SparkContext.\u活动\u spark\u上下文
--->35返回sc.\u jvm.functions.lit(文字)
36
37
/usr/local/spark/python/lib/py4j-0.10.3-src.zip/py4j/java_gateway.py in____调用(self,*args)
1122
1123定义调用(self,*args):
->1124 args\u命令,temp\u args=self.\u build\u args(*args)
1125
1126 command=proto.CALL\u command\u NAME+\
/usr/local/spark/python/lib/py4j-0.10.3-src.zip/py4j/java_gateway.py in_build_args(self,*args)
1092
1093 args_command=“”.加入(
->1094[get_command_part(arg,self.pool)用于新参数中的参数])
1095
1096返回参数命令,临时参数
/get_命令_部分中的usr/local/spark/python/lib/py4j-0.10.3-src.zip/py4j/protocol.py(参数,python_代理_池)
287命令_部分+=“;”+接口
288其他:
-->289命令\u部分=引用\u类型+参数。\u获取\u对象\u id()
290
291命令\u部分+=“\n”
AttributeError:“广播”对象没有属性“\u获取\u对象\u id”

关于如何根据广播列表过滤pyspark 2.0数据帧,您有什么想法吗?

您不能直接访问数据帧函数中的广播变量,而是使用“值”访问广播变量的值

因此,请按如下方式修改您的代码:

filterListB= sc.broadcast(filterList)
filter_df= df.where((df['Foo'].isin(filterListB.value)) | (df['Bar'].isin(filterListB.value)))

参考:

您不能在数据帧函数中直接访问广播变量,而是使用“值”访问广播变量的值

因此,请按如下方式修改您的代码:

filterListB= sc.broadcast(filterList)
filter_df= df.where((df['Foo'].isin(filterListB.value)) | (df['Bar'].isin(filterListB.value)))

参考资料:

如果您有一个长度仅为50-100的短列表,则无需广播。您可以通过全局变量直接使用它。只有大尺寸的对象才需要广播。如果你有一个长度只有50-100的短列表,那么就没有必要广播它。您可以通过全局变量直接使用它。只有大尺寸的物体才需要广播。