Apache spark PySpark:嵌套式将一列拆分为多个新列
我在Hadoop上有一个Apache spark PySpark:嵌套式将一列拆分为多个新列,apache-spark,pyspark,apache-spark-sql,spark-dataframe,pyspark-sql,Apache Spark,Pyspark,Apache Spark Sql,Spark Dataframe,Pyspark Sql,我在Hadoop上有一个network.log: {“Source”:“Network”,“Detail”:“Event=01 | Device=Mobile | ClientIP=10.0.0.0 | URL=example.com”} 我想用|将其加载为数据帧拆分详细信息。然后,我想使用=进一步拆分每个新列,左侧部分作为列名,右侧部分作为值 预期结果将是: Source | Event | Device | ClientIP | URL Network | 01 | Mobile |
network.log
:
{“Source”:“Network”,“Detail”:“Event=01 | Device=Mobile | ClientIP=10.0.0.0 | URL=example.com”}
我想用|
将其加载为数据帧拆分详细信息
。然后,我想使用=
进一步拆分每个新列,左侧部分作为列名,右侧部分作为值
预期结果将是:
Source | Event | Device | ClientIP | URL
Network | 01 | Mobile | 10.0.0.0 | example.com
我做了第一次拆分,如下所示:
从pyspark导入SparkContext
从pyspark.sql导入函数中,选择SQLContext
输入路径='network.log'
sc=SparkContext(“本地”、“网络事件”)
sqlContext=sqlContext(sc)
raw=sqlContext.read.json(输入路径)
detail\u col=functions.split(原始['detail'],'\\124;')
对于范围(4)中的i:
raw=raw.WITH列('col_uu'+str(i),detail_ucol.getItem(i))
raw.show()
我的问题是,我可以在detail\u col.getItem(I)
的基础上同时进行第二次拆分吗?我可以考虑为新数据框的每一列创建另一个UDF,但是在一个UDF中是否有更优雅的方式?非常感谢
注意:我正在使用Spark 1.5.0,因此熊猫的UDF将不可用 在1.5.0中,可以使用
regexp\u extract
from pyspark.sql import functions as F
for i in ['Event', 'Device', 'ClientIP', 'URL']:
df = df.withColumn(i, F.regexp_extract('Detail',"{}=([^\|]+)".format(i),1))
df.show()
+-------+--------------------+-----+------+--------+-----------+
| Source| Detail|Event|Device|ClientIP| URL|
+-------+--------------------+-----+------+--------+-----------+
|Network|Event=01|Device=M...| 01|Mobile|10.0.0.0|example.com|
+-------+--------------------+-----+------+--------+-----------+
在1.5.0中,可以使用
regexp\u extract
from pyspark.sql import functions as F
for i in ['Event', 'Device', 'ClientIP', 'URL']:
df = df.withColumn(i, F.regexp_extract('Detail',"{}=([^\|]+)".format(i),1))
df.show()
+-------+--------------------+-----+------+--------+-----------+
| Source| Detail|Event|Device|ClientIP| URL|
+-------+--------------------+-----+------+--------+-----------+
|Network|Event=01|Device=M...| 01|Mobile|10.0.0.0|example.com|
+-------+--------------------+-----+------+--------+-----------+
无需为此编写UDF,您可以应用许多备选方案并实现这一点,以下是备选方案之一:-
from pyspark import SparkContext
from pyspark.sql import functions
INPUT_PATH = 'network.log'
sc = SparkContext("local", "NetworkEvent")
sqlContext = SQLContext(sc)
raw = sqlContext.read.json(INPUT_PATH)
detail_col = functions.split(raw['Detail'], '\|')
cols_to_be = raw.select([functions.split(detail_col.getItem(i), "=").getItem(0).alias("col_"+str(i)) for i in range(4)]).first()
for i in range(4):
raw = raw.withColumn(
cols_to_be["col_"+str(i)],
functions.split(detail_col.getItem(i), "=").getItem(1)
)
raw.show()
+--------------------+-------+-----+------+--------+-----------+
| Detail| Source|Event|Device|ClientIP| URL|
+--------------------+-------+-----+------+--------+-----------+
|Event=01|Device=M...|Network| 01|Mobile|10.0.0.0|example.com|
+--------------------+-------+-----+------+--------+-----------+
希望您的详细信息数据应遵循一种模式。无需为此编写自定义项,您可以应用多种备选方案并实现这一目标,以下是备选方案之一:-
from pyspark import SparkContext
from pyspark.sql import functions
INPUT_PATH = 'network.log'
sc = SparkContext("local", "NetworkEvent")
sqlContext = SQLContext(sc)
raw = sqlContext.read.json(INPUT_PATH)
detail_col = functions.split(raw['Detail'], '\|')
cols_to_be = raw.select([functions.split(detail_col.getItem(i), "=").getItem(0).alias("col_"+str(i)) for i in range(4)]).first()
for i in range(4):
raw = raw.withColumn(
cols_to_be["col_"+str(i)],
functions.split(detail_col.getItem(i), "=").getItem(1)
)
raw.show()
+--------------------+-------+-----+------+--------+-----------+
| Detail| Source|Event|Device|ClientIP| URL|
+--------------------+-------+-----+------+--------+-----------+
|Event=01|Device=M...|Network| 01|Mobile|10.0.0.0|example.com|
+--------------------+-------+-----+------+--------+-----------+
希望您的详细信息数据应该遵循一种模式。详细信息中的列数是固定的吗?你总是有相同的列吗?@Steven是的,每个记录都有相同的模式,即固定的列数。你的详细列数是固定的吗?你总是有相同的列吗?@Steven是的,每条记录都有相同的模式,即固定的列数。谢谢。最初,我想从数据本身中提取列名,以便为模式保存一些手动输入,因为有很多列,但是您发布的解决方案也很好。谢谢。最初,我想从数据本身中提取列名,以便为模式保存一些手动输入,因为有许多列,但是您发布的解决方案也很好。是的,
Detail
列具有固定模式。感谢您提供的解决方案~是,详细信息
列具有固定模式。谢谢你的解决方案~