PySpark DataFrame中网络IP地址格式转换的最佳实践
IP地址补零拼接为定长字符串的Spark实现
你之前用StringIndexer拿不到正确结果是正常的——这个组件是Spark MLlib里做类别特征编码的,作用是把字符串类型的分类标签映射成从0开始的连续数值索引,根本不是用来做字符串格式转换的,选工具就选错了。
实现逻辑
不用写UDF,全用Spark内置函数就能实现,性能比自定义函数高很多,处理TB级IP数据也不会有性能瓶颈,步骤很简单:
- 用
.做分隔符把IP拆成4段的数组,注意正则匹配里.要转义成\\. - 对每一段做左补零,固定长度为3位,不足的位置补0
- 去掉分隔符,把4段补完零的字符串直接拼起来,就是要的12位结果
代码示例
PySpark
from pyspark.sql import SparkSession from pyspark.sql.functions import split, lpad, concat_ws, col spark = SparkSession.builder.appName("ip_format").getOrCreate() # 测试数据 df = spark.createDataFrame([ ("10.220.50.51",), ("2.2.2.4",), ("192.168.1.1",) ], schema=["IP"]) # 转换 res_df = df.withColumn( "new IP", concat_ws("", *[lpad(split(col("IP"), "\\.")[i], 3, "0") for i in range(4)]) ) res_df.show()
Scala Spark
import org.apache.spark.sql.functions._ val df = Seq("10.220.50.51", "2.2.2.4", "192.168.1.1").toDF("IP") val resDf = df.withColumn( "new IP", concat((0 until 4).map(i => lpad(split(col("IP"), "\\.")(i), 3, "0")): _*) ) resDf.show()
输出结果
运行后输出完全符合要求:
+------------+------------+ |IP |new IP | +------------+------------+ |10.220.50.51|010220050051| |2.2.2.4 |002002002004| |192.168.1.1 |192168001001| +------------+------------+
你给的示例里
192.168.1.1对应的结果192168100100属于笔误,按照每段补前导零到3位的规则,正确结果是192168001001,如果有特殊的补位规则改下lpad的参数就行。
如果源数据里有不合法的IP(比如段数不对、段值超过255、含非数字字符),建议在转换前加一层校验过滤,避免任务报错。
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

