2017-05-02 84 views
1

這是我擁有的數據:在pyspark中,如何通過一列數據幀循環過濾功能?

**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'])) 

但它不工作。有沒有辦法使用基本火花功能製作UDF?

因此,我將名稱列放入列表中並循環遍歷列表,但速度超慢,我相信這種方式我沒有做分佈式計算。

1)我的首要任務是弄清楚如何通過基本功能(例如spark_df.filter)在一列pyspark數據幀中循環信息。

2)我們可以先將名稱列寫入RDD,然後使用我的UDF循環訪問RDD,那麼可以利用分佈式計算的優勢嗎?

3)如果我有2代表具有相同的結構(名稱/電影),但不同年份,如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 
**name** **movie** 
jason  b 
jason  c 
mike   a 
bruce  c 

和我的想法是用 '年' 列Concat的2代表一起,和使用一個數據透視表來獲得所需的結構。

回答

0

,我建議由collect_list使用的,而不是把整個數據幀到RDD groupby隨訪。之後您可以應用UDF。現在

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| 
+-----+--------------------+--------+ 
+0

謝謝,但我的問題1如何使用UDF基本pyspark功能,我編輯我的問題。我還想學習的是按列中的值對數據幀進行分片,然後對這些子集進行轉換。 – Olap

+0

@Olap,我根據你的問題改變了我的解決方案。仍然建議使用'groupby'。你可以在之後申請udf。 – titipata

+0

非常感謝,我還有一個關於玩多桌的問題,你能幫忙嗎?我已經更新了這個問題 – Olap