簡體   English   中英

如何按屬性/鍵過濾 RDD,然后使用 pyspark 應用 function?

[英]How to filter RDD by attribute/key and then apply function using pyspark?

我有一些示例數據:

my_data = [{'id': '001', 'name': 'Sam', 'class': "classA", 'age': 15, 'exam_score': 90},
           {'id': '002', 'name': 'Tom', 'class': "classA", 'age': 15, 'exam_score': 78},
           {'id': '003', 'name': 'Ben', 'class': "classB", 'age': 16, 'exam_score': 91},
           {'id': '004', 'name': 'Max', 'class': "classB", 'age': 16, 'exam_score': 76},
           {'id': '005', 'name': 'Ana', 'class': "classA", 'age': 15, 'exam_score': 88},
           {'id': '006', 'name': 'Ivy', 'class': "classA", 'age': 16, 'exam_score': 77},
           {'id': '007', 'name': 'Eva', 'class': "classB", 'age': 15, 'exam_score': 86},
           {'id': '008', 'name': 'Zoe', 'class': "classB", 'age': 16, 'exam_score': 89}]

my_rdd = sc.parallelize(my_data)
my_rdd

假設我有一些簡單的 function:

def divide_by_100(value):
  return value/100

目標是用 function 將所有考試分數除以 100,然后找到最低分數。 我的想法是:

  • 按鍵過濾 my_rdd,以便只保留exam_score中的值
  • divide_by_100() function 應用於此
  • 使用.min().collect() function 打印數據中的最低考試分數

我知道groupByKey()也可以使用。

問題是我不知道如何使用pyspark將其付諸實踐。 對此有任何幫助將不勝感激。

沒有任何鍵的最低分數:

score_rdd = my_rdd.map(lambda my_dict: my_dict['exam_score']/100)
print(score_rdd.min())
# 0.76

這是使用 pyspark rdd 的解決方案:

score_rdd = my_rdd.map(lambda my_dict: (my_dict['class'], my_dict['exam_score']/100))
print(score_rdd.collect())
# [('classA', 0.9), ('classA', 0.78), ('classB', 0.91), ('classB', 0.76), ('classA', 0.88), ('classA', 0.77), ('classB', 0.86), ('classB', 0.89)]
from builtins import min # import python function: min
class_min_rdd = score_rdd.reduceByKey(min)
print(class_min_rdd.collect())
# [('classA', 0.77), ('classB', 0.76)]

這是使用 pyspark dataframe 的解決方案:

from pyspark.sql.types import *
from pyspark.sql.functions import *

df = my_rdd.toDF()
df.printSchema()
# root
#  |-- age: long (nullable = true)
#  |-- class: string (nullable = true)
#  |-- exam_score: long (nullable = true)
#  |-- id: string (nullable = true)
#  |-- name: string (nullable = true)
df = df.withColumn('score', col('exam_score')/100).groupBy('class').agg(min('score').alias('score'))
df.show(10, False)
# +------+-----+
# |class |score|
# +------+-----+
# |classB|0.76 |
# |classA|0.77 |
# +------+-----+
print(df.collect())
# [Row(class='classB', score=0.76), Row(class='classA', score=0.77)]

為什么要使用收集或使用 RDD,請改用 Dataframe

df = my_rdd.toDF()
import pyspark.sql.functions as F
from pyspark.sql.functions import *

from pyspark.sql.window import Window
windowSpec = Window.partitionBy('class').orderBy('exam_score')
df1=df.withColumn("rank",rank().over(windowSpec))
w = Window.partitionBy('class')
df1.withColumn('minB', F.min('rank').over(w)).where(F.col('rank') == F.col('minB')).drop('minB').withColumn('exam_score',(df1.exam_score)/100).drop('rank').show()

+---+------+----------+---+----+
|age| class|exam_score| id|name|
+---+------+----------+---+----+
| 16|classB|      0.76|004| Max|
| 16|classA|      0.77|006| Ivy|
+---+------+----------+---+----+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM