2016-11-24 18 views
1

我正在讀取包含某些字段(如設備ID,imei等)的鑲木地板文件。 此鑲木地板文件是通過讀取由cascading.tuple.Tuple S)。如何從包含無法讀取的字符的火花數據幀中過濾掉行

某些行包含我想完全溝通的不可讀字符。

這裏是我正在讀文件:

val sparkSession = SparkSession.builder().master(sparkMaster).appName(sparkAppName).config("spark.driver.memory", "32g").getOrCreate() 

sparkSession.sparkContext.hadoopConfiguration.set("io.serializations", "cascading.tuple.hadoop.TupleSerialization") 

val df=sparkSession.read.parquet("hdfs://**.46.**.2*2:8020/test/oldData.parquet") 

df.printSchema() 

val filteredDF=df.select($"$DEVICE_ID", $"$DEVICE_ID_NEW", $"$IMEI」, $」$WIFI_MAC_ADDRESS", $"$BLUETOOTH_MAC_ADDRESS", $"$TIMESTAMP").filter($"$TIMESTAMP" > 1388534400 && $"$TIMESTAMP" < 1483228800) 

filteredDF.show(100) 

import org.apache.spark.sql.functions.{udf,col,regexp_replace,trim} 

val len=udf{ColVal:String => ColVal.size} 

val new1DF=filteredDF.select(trim(col("deviceId"))) 

new1DF.show(100) 

val newDF=new1DF.filter((len(col("deviceId")) <20)) 

newDF.show(100) 

即使對長度小於20的設備ID應用過濾器後,我仍然得到具有含大多空格很長的設備ID的行和不可讀的字符。

有人可以指出一些可能會幫助我過濾這些行的線索。

我也嘗試過濾出包含特價商品的設備ID。使用此:

df.filter($ 「$ DEVICE_ID」 RLIKE 「/ [^ \ uFFFD]/G」)

我有一個空的數據幀。

架構:

root 
|-- deviceId: string (nullable = true) 
|-- deviceIdNew: string (nullable = true) 
|-- imei: string (nullable = true) 
|-- wifiMacAddress: string (nullable = true) 
|-- bluetoothMacAddress: string (nullable = true) 
|-- timestamp: long (nullable = true) 

與不可讀的字符行數:

+--------------------+ 
|  trim(deviceId)| 
+--------------------+ 
|     | 
|+~C���...| 
|��� 
    Cv�...| 
|��� 
    Cv�...| 
|    �#Inten| 
|    �$ 
        �| 
|     | 
|     | 
|     | 
|     | 
| 0353445a712d877b| 
| 0577bc8a29754939| 
| 0577bc8a29754939| 
| 0577bc8a29754939| 
| 0577bc8a29754939| 
| 0577bc8a29754939| 
| 0577bc8a29754939| 
| 0577bc8a29754939| 
| 08bdae9e37b48080| 

UNREADABLE ROW VALUES

回答

0

您可以通過正則表達式進行篩選。 例如,您可以使用regex_replace用一些值(例如21個字符常量或者甚至是空字符串)替換所有帶有不可讀字符(即除字母數字或可打印或您決定的任何內容之外的所有字符),然後根據此過濾值進行過濾。

0
val filteredDF=df.select("deviceId") 
        .filter((len(col("deviceId")) <17)) 
        .filter($"$DEVICE_ID" rlike "^([A-Z]|[0-9]|[a-z])+$") 

解決了這個問題。

我以前沒有使用的是正則表達式通配符^用於比賽開始,$用於比賽結束。這確保只有具有完全匹配deviceId值的行才能通過過濾器。

This website真的幫助我生成和測試所需的正則表達式。

相關問題