java-spark的各種常用算子的寫法
通常寫spark的程序用scala比較方便,畢竟spark的源碼就是用scala寫的。然而,目前java開發者特別多,尤其進行數據對接、上線服務的時候,這時候,就需要掌握一些spark在java中的使用方法了
一、map
map在進行數據處理、轉換的時候,不能更常用了
在使用map之前 首先要定義一個轉換的函數 格式如下:
Function<String, LabeledPoint> transForm = new Function<String, LabeledPoint>() {//String是某一行的輸入類型 LabeledPoint是轉換後的輸出類型 @Override public LabeledPoint call(String row) throws Exception {//重寫call方法 String[] rowArr = row.split(","); int rowSize = rowArr.length; double[] doubleArr = new double[rowSize-1]; //除了第一位的lable外 其余的部分解析成double 然後放到數組中 for (int i = 1; i < rowSize; i++) { String each = rowArr[i]; doubleArr[i] = Double.parseDouble(each); } //用剛才得到的數據 轉成向量 Vector feature = Vectors.dense(doubleArr); double label = Double.parseDouble(rowArr[0]); //構造用於分類訓練的數據格式 LabelPoint LabeledPoint point = new LabeledPoint(label, feature); return point; } };
需要特別註意的是:
1、call方法的輸入應該是轉換之前的數據行的類型 返回值應是處理之後的數據行類型
2、如果轉換方法中調用了自定義的類,註意該類名必須實現序列化 比如
public class TreeEnsemble implements Serializable { }
3、轉換函數中如果調用了某些類的對象,比如該方法需要調用外部的一個參數,或者數值處理模型(標準化,歸一化等),則該對象需要聲明是final
然後就是在合適的時候調用該轉換函數了
JavaRDD<LabeledPoint> rdd = oriData.toJavaRDD().map(transForm);
這種方式是需要將普通的rdd轉成javaRDD才能使用的,轉成javaRDD的這一步操作不耗時,不用擔心
二、filter
在避免數據出現空值、0等場景中也非常常用,可以滿足sql中where的功能
這裏首先也是要定義一個函數,該函數給定數據行 返回布爾值 實際效果是將返回為true的數據保留
Function<String, Boolean> boolFilter = new Function<String, Boolean>() {//String是某一行的輸入類型 Boolean是對應的輸出類型 用於判斷數據是否保留 @Override public Boolean call(String row) throws Exception {//重寫call方法 boolean flag = row!=null; return flag; } };
通常該函數實際使用中需要修改的僅僅是row的類型 也就是數據行的輸入類型,和上面的轉換函數不同,此call方法的返回值應是固定為Boolean
然後是調用方式
JavaRDD<LabeledPoint> rdd = oriData.toJavaRDD().filter(boolFilter);
三、mapToPair
該方法和map方法有一些類似,也是對數據進行一些轉換。不過此函數輸入一行 輸出的是一個元組,最常用的方法是用來做交叉驗證 或者統計錯誤率 召回率 計算AUC等等
同樣,需要先定義一個轉換函數
Function<String, Boolean> transformer = new PairFunction<LabeledPoint, Object, Object>() {//LabeledPoint是輸入類型 後面的兩個Object不要改動 @Override public Tuple2 call(LabeledPoint row) throws Exception {//重寫call方法 通常只改動輸入參數 輸出不要改動 double predicton = thismodel.predict(row.features()); double label = row.label(); return new Tuple2(predicton, label); } });
關於調用的類、類的對象,要求和之前的一致,類需要實現序列化,類的對象需要聲明成final類型
相應的調用如下:
JavaPairRDD<Object, Object> predictionsAndLabels = oriData.mapToPair(transformer);
然後對該predictionsAndLabels的使用,計算準確率、召回率、精準率、AUC,接下來的博客中會有,敬請期待
如有補充,或者質疑,或者有相關問題,請發郵件給我,或者直接回復 郵箱:[email protected]
java-spark的各種常用算子的寫法