在正式建模之前,需要非常瞭解建模所要用到的資料,本文主要介紹一些常見的資料觀測和處理方法。 1.資料觀測
(1)統計資料表中每一列資料的缺失率
%pyspark#構造未經處理資料範例df = spark.createDataFrame([ (1,175,72,28,'M',10000), (2,171,70,45,'M',None), (3,172,None,None,None,None), (4,180,78,33,'M',None), (5,None,48,54,'F',None), (6,160,45,30,'F',5000), (7,169,65,None,'M',5000),], ['id','height','weight','age','gender','income'])res_df = df.rdd.map(lambda x:x).map(list).collect()#統計每列的資料缺失率for i in range(6): #擷取第i列資料 columns = [item[i] for item in res_df] #統計第i列資料中非空的資料數 count = sum([1 for item in columns if item]) #計算第i列的資料缺失率 missing_rate = 1 - count/len(res_df) print("第{}列的資料缺失率為:{:.4f}%".format(i+1,missing_rate*100))
輸出結果如下所示:
(2)統計指定列資料的詳細資料
%pyspark from pyspark.sql import functions as F#構造未經處理資料範例df = spark.createDataFrame([ (1,175,72,28,'M',10000), (2,171,70,45,'M',8000), (3,172,None,27,'F',7000), (4,180,78,30,'M',4000), (5,None,48,54,'F',6000), (6,160,45,30,'F',5000), (7,169,65,36,'M',7500),], ['id','height','weight','age','gender','income'])#先基於gender分組,然後用各種彙總函式(max,min,mean,stddev)統計age列的資訊df_summary = sorted(df.groupBy(df.gender).agg(F.max(df.age),F.min(df.age),F.mean(df.age),F.stddev(df.age)).collect())print(df_summary )
輸出結果如下所示:
(3)擷取DataFrame中Vector的資料資訊
%pysparkfrom pyspark.ml.linalg import Vectorsdf = sc.parallelize([ ("assert",Vectors.dense([1,2,3])), ("require",Vectors.sparse(3,{1:2})), ("announce",Vectors.sparse(3,{0:1,2:4})) ]).toDF(["word","vector"])#提取DataFrame中的Vector中的資料資訊def extract(row): return (row.word,) + tuple(row.vector.toArray().tolist()) res_df = df.rdd.map(extract).toDF(["word","v_1","v_2","v_3"])res_df.show()#擷取指定列的資料print(res_df.select("word","v_1").show())
輸出結果如下所示:
2.資料處理
本部分主要記錄一些資料處理的小技巧。
(1)為列表產生索引
%pyspark#通過enumerate為col_list產生索引col_list = ['username','id','gender','age']mapping_list = list(enumerate(sorted(col_list)))print(mapping_list)
輸出結果如下所示:
(2)將list轉換成dict
%pyspark#將mapping_list中的key和value互換位置,並轉換為dictrevs_maplist = {value:idx for [idx,value] in mapping_list}print(revs_maplist)
輸出結果如下所示:
(3)嵌套for迴圈簡寫
%pysparktest_list = [1,2,-3,10,None,-5,0,10.5]#for迴圈簡寫1 (此處if在for迴圈後面)result1 = [2*item for item in test_list if item != None]print(result1)#for迴圈簡寫2 (此處if-else必須同時存在且在for迴圈前面)result2 = [1 if item > 0 else 0 for item in result1]print(result2)
輸出結果如下所示:
(4)以指定條件增加新列
%pyspark from pyspark.sql import functions as F #構造未經處理資料範例 df = spark.createDataFrame([ (1,175,72,28,'M',10000), (2,171,70,45,'M',8000), (3,172,None,None,'F',7000), (4,180,78,33,'M',4000), (5,None,48,54,'F',6000), (6,160,45,30,'F',5000), (7,169,65,None,'M',7500),], ['id','height','weight','age','gender','income']) #1.給df增加一列資料'income2',income2 = income + 2000.test1 = df.withColumn("income2",df.income + 2000)#print(test1.show())#2.給test1增加一列資料'label',當gender=='M'時,label=1,否則label=0.test2 = test1.withColumn("label",F.when(test1.gender == 'M',1).otherwise(0))print(test2.show())
輸出結果如下所示: