2016-11-24 7 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")

を。

SCHEMA:読めない文字で

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) 

ROWS:

+--------------------+ 
|  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は、本当に目的の正規表現を生成してテストするのに役立ちました。