如何从包含不可读字符的Spark DataFrame中滤除行



我正在阅读一个包含某些字段的镶木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个字符恒定甚至是空字符串)替换所有具有不可读字符(即除字母数字或可打印或其他决定的所有内容),然后按照此滤过。

>>>>>

相关内容

  • 没有找到相关文章

最新更新