Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark PySpark:嵌套式将一列拆分为多个新列_Apache Spark_Pyspark_Apache Spark Sql_Spark Dataframe_Pyspark Sql - Fatal编程技术网

Apache spark PySpark:嵌套式将一列拆分为多个新列

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 |

我在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 | 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
列具有固定模式。感谢您提供的解决方案~是,
详细信息
列具有固定模式。谢谢你的解决方案~