Pyspark 根據行內容拆分DataFrame

由於最近業務遇到了這個場景,而百度後沒有找到解決方法。

我是通過Stack Overflow的提問,獲得了可以實現的答案。

原問題地址是:https://stackoverflow.com/questions/58317153/how-to-split-the-pyspark-dataframe-based-on-the-content-of-the-line。如果有其他解決方法我也會及時更新。

下面詳細描述一下需求。


原始數據示例如下:

+------------+
|       value|
+------------+
|Date20191009|
|           1|
|           2|
|           3|
|Date20191010|
|           1|
|           4|
|           5|
+------------+

可以看到,原始數據爲1列PySpark DataFrame格式。這1列的數據包括兩類

  1. 文件名(例如“ DATE20191009”)
  2. 文件內容(例如“ 1”,“ 2”,“ 3”)

最終期望結果如下:

+------------+-------+
|       value|content|
+------------+-------+
|Date20191009|  1,2,3|
|Date20191010|  1,4,5|
+------------+-------+

可以看到,期望實現的功能是,將1列數據分爲文件名和文件內容。

注意事項爲:

  1. 文件名和內容的區分在於,是否Date開頭。
  2. 兩個文件名之間的內容,認爲是第一個文件名的內容。
  3. 各文件名的內容並不等長,因此不能直接取間隔劃分。

用Pyspark實現的代碼如下:

from pyspark.sql import SparkSession

from pyspark.sql.functions import *
from pyspark.sql.window import Window

spark = SparkSession.builder.appName("DataFrame").getOrCreate()

df = spark.read.text("C:\\mypath\\myfile.txt")

w = Window.rowsBetween(Window.unboundedPreceding, 0)
df1 = df.withColumn('tmp', when(df.value.startswith('Date'), df.value).otherwise(None)).withColumn('temp', last('tmp',
                                                                                                                True).over(
    w)).drop('tmp')
df1.show()

df2 = df1.filter(df1.value != df1.temp).groupBy(df1.temp).agg(
    concat_ws(',', collect_list(df1.value)).alias('content')).withColumnRenamed("temp", "value")
df2.show()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章