PySpark 在多个列上应用相同的 StringIndexer

San*_*ari 5 python dataframe pyspark

我有以下数据框

+--------------+---------------+   
|       SrcAddr|        DstAddr|   
+--------------+---------------+  
| 192.168.100.5| 192.168.220.16|  
| 192.168.100.5| 192.168.220.15|  
|192.168.220.15|  192.168.100.5|  
|192.168.220.16|  192.168.100.5|  
| 192.168.100.5| 192.168.220.15|  
|192.168.220.16|  192.168.100.5|  
| 192.168.220.9|  192.168.100.5|  
| 192.168.100.5|  192.168.220.9|  
| 192.168.220.9|  192.168.100.5|  
+--------------+---------------+  
Run Code Online (Sandbox Code Playgroud)

包含源地址和目标地址IP。我想通过 StringIndexer 将它们转换为数字索引,但我想学习列之间的通用映射。

不幸的是,StringIndexer 在 PySpark 中没有提供如此丰富的接口。因此我找到了一个解决方法,但我想知道是否有更好的方法。

我所做的如下:
首先,我计算两列之间的并集

src_addr_df = df.select(["SrcAddr"]).withColumnRenamed("SrcAddr", "Addr")  
dst_addr_df = df.select(["DstAddr"]).withColumnRenamed("DstAddr", "Addr")  
all_addr_df = src_addr_df.union(dst_addr_df)  
Run Code Online (Sandbox Code Playgroud)

然后,我在新创建的 DataFrame 上学习了一个通用的 StringIndexer:

addrIndexer = StringIndexer(inputCol="Addr", outputCol="AddrIdx")  
addrModel = addrIndexer.fit(all_addr_df)  
Run Code Online (Sandbox Code Playgroud)

最后,我使用学习到的模型来转换原始数据帧。这是棘手的部分,因为我需要经常重命名列以获得所需的结果:

df = addrModel.transform(df.withColumnRenamed("SrcAddr", "Addr")).withColumnRenamed("Addr", "SrcAddr").withColumnRenamed("AddrIdx", "SrcAddrIdx")

df = addrModel.transform(df.withColumnRenamed("DstAddr", "Addr")).withColumnRenamed("Addr", "DstAddr").withColumnRenamed("AddrIdx", "DstAddrIdx")
Run Code Online (Sandbox Code Playgroud)

因此,我想知道是否有可能更改 StringIndexer 的 InputCol 值,这将创建一个更易读的代码

最好的问候,桑德罗