我正在阅读一个包含某些字段的镶木quet文件,例如设备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,其中大部分包含Whitespaces和不可读的字符。
可以指出一些线索可能有助于我过滤这样的行。
我还尝试过滤出包含特价的设备ID。使用以下方式:
df.filter($" $"
我有一个空的数据框。
模式:
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|
不可读的行值
val filteredDF=df.select("deviceId")
.filter((len(col("deviceId")) <17))
.filter($"$DEVICE_ID" rlike "^([A-Z]|[0-9]|[a-z])+$")
解决了问题。
我之前不使用的是Regex Wild卡^
开始比赛,而$
的比赛结束。这样可以确保只有具有完全匹配的deviceId
值的行通过过滤器。
这个网站确实帮助我生成和测试所需的正则表达式。
您可以通过正则表达式过滤。例如,您可以使用Regex_replace用某些值(例如21个字符恒定甚至是空字符串)替换所有具有不可读字符(即除字母数字或可打印或其他决定的所有内容),然后按照此滤过。
>>>>>