Python 在pyspark中,如何通过一列数据帧循环过滤函数?

Python 在pyspark中,如何通过一列数据帧循环过滤函数?,python,pyspark,udf,Python,Pyspark,Udf,这是我掌握的数据: **name** **movie** jason a jason b jason c mike a mike b bruce a bruce c ryan b 我的目标是让这个 **name** **# of moive** jason a,b,c mike a,b bruce a,c ryan b

这是我掌握的数据:

**name** **movie**
jason        a
jason        b
jason        c
mike         a
mike         b
bruce        a
bruce        c
ryan         b
我的目标是让这个

**name** **# of moive**
jason       a,b,c
mike         a,b
bruce        a,c
ryan          b
我正在使用pyspark并尝试使用UDF来完成这项工作。我定义了这个函数,spark给了我一个错误,因为它调用了基本函数“filter”,这会导致启动新工作程序时出现问题(如果没有,请更正我)

我的逻辑是首先使用过滤器生成子集,然后行数就是电影数。在这之后,我用这个UDF创建了一个新的专栏

def udf(user_name):
    return df.filter(df['name'] == user_name).select('movie').dropDuplictes()\
                                    .toPandas['movie'].tolist()

df.withColumn('movie_number', udf(df['name']))
但它不起作用。有没有一种方法可以用基本的spark函数生成一个UDF

所以我把name列做成一个列表,然后在列表中循环,但是速度非常慢,我相信这样我就不会做分布式计算了

1) 我的首要任务是找出如何使用
spark\u df.filter
等基本函数循环pyspark数据帧的一列中的信息

2) 我们是否可以先将name列生成一个RDD,然后使用我的UDF循环该RDD,这样就可以利用分布式计算的优势

3) 如果我有两个表具有相同的结构(名称/电影),但年份不同,如2005年和2007年,我们能否有一种有效的方法来制作第三个表,其结构是:

**name** **movie** **in_2005** **in_2007** 
jason        a          1           0
jason        b          0           1
jason        c          1           1
mike         a          0           1
mike         b          1           0
bruce        a          0           0
bruce        c          1           1
ryan         b          1           0
1和0表示这家伙是否在2005/2007年对这部电影发表了评论。在这种情况下,原始表格应为:

2005年:

**name** **movie**
jason        a
jason        c
mike         b
bruce        c
ryan         b
2007年


我的想法是将这两个表与一个“年”列合并在一起,并使用一个透视表来获得所需的结构。

我建议使用
groupby
然后是
collect\u list
,而不是将整个数据帧转换为RDD。您可以在以后应用自定义项

import pyspark.sql.functions as func

# toy example dataframe
ls = [
    ['jason', 'movie_1'],
    ['jason', 'movie_2'],
    ['jason', 'movie_3'],
    ['mike', 'movie_1'],
    ['mike', 'movie_2'],
    ['bruce', 'movie_1'],
    ['bruce', 'movie_3'],
    ['ryan', 'movie_2']
]
df = spark.createDataFrame(pd.DataFrame(ls, columns=['name', 'movie']))

df_movie = df.groupby('name').agg(func.collect_list(func.col('movie')))
现在,这是一个创建
udf
以处理新列
movies
的示例。我只是举一个例子,说明如何计算每行的长度

def movie_len(movies):
    return len(movies)
udf_movie_len = func.udf(movie_len, returnType=StringType())

df_movie.select('name', 'movies', udf_movie_len(func.col('movies')).alias('n_movies')).show()
这将提供:

+-----+--------------------+--------+
| name|              movies|n_movies|
+-----+--------------------+--------+
|jason|[movie_1, movie_2...|       3|
| ryan|           [movie_2]|       1|
|bruce|  [movie_1, movie_3]|       2|
| mike|  [movie_1, movie_2]|       2|
+-----+--------------------+--------+

我建议使用
groupby
后跟
collect\u list
,而不是将整个数据帧转换为RDD。您可以在以后应用自定义项

import pyspark.sql.functions as func

# toy example dataframe
ls = [
    ['jason', 'movie_1'],
    ['jason', 'movie_2'],
    ['jason', 'movie_3'],
    ['mike', 'movie_1'],
    ['mike', 'movie_2'],
    ['bruce', 'movie_1'],
    ['bruce', 'movie_3'],
    ['ryan', 'movie_2']
]
df = spark.createDataFrame(pd.DataFrame(ls, columns=['name', 'movie']))

df_movie = df.groupby('name').agg(func.collect_list(func.col('movie')))
现在,这是一个创建
udf
以处理新列
movies
的示例。我只是举一个例子,说明如何计算每行的长度

def movie_len(movies):
    return len(movies)
udf_movie_len = func.udf(movie_len, returnType=StringType())

df_movie.select('name', 'movies', udf_movie_len(func.col('movies')).alias('n_movies')).show()
这将提供:

+-----+--------------------+--------+
| name|              movies|n_movies|
+-----+--------------------+--------+
|jason|[movie_1, movie_2...|       3|
| ryan|           [movie_2]|       1|
|bruce|  [movie_1, movie_3]|       2|
| mike|  [movie_1, movie_2]|       2|
+-----+--------------------+--------+

谢谢,但我的问题1是如何将UDF与基本pyspark函数一起使用,我编辑了我的问题。我还想学习的是按列中的值对数据帧进行切片,然后对这些子集进行转换。@Olap,我根据您的问题更改了我的解决方案。仍然建议使用
groupby
。你可以在以后申请udf。非常感谢,我还有一个关于玩多张桌子的问题,你能帮我吗?顺便问一下,我已经更新了这个问题,从技术上讲,有没有一种方法可以将列表制作成RDD,然后使用UDF循环列表?(我试过了,但它通过了整个RDD而不是值)如果是这样,它是在进行分布式计算吗?在这种情况下,你甚至不需要UDF,因为你可以直接将函数应用到RDD。谢谢,但我的问题1是如何将UDF与基本pyspark函数一起使用,我编辑了我的问题。我还想学习的是按列中的值对数据帧进行切片,然后对这些子集进行转换。@Olap,我根据您的问题更改了我的解决方案。仍然建议使用
groupby
。你可以在以后申请udf。非常感谢,我还有一个关于玩多张桌子的问题,你能帮我吗?顺便问一下,我已经更新了这个问题,从技术上讲,有没有一种方法可以将列表制作成RDD,然后使用UDF循环列表?(我试过了,但它通过了整个RDD而不是值)如果是这样,它是在进行分布式计算吗?在这种情况下,您甚至不需要UDF,因为您可以直接将函数应用于RDD。