簡體   English   中英

基於分隔符拆分字符串列並為 Pyspark 中的每個值創建列

[英]Split string column based on delimiter and create columns for each value in Pyspark

我有 1000 個包含以下格式數據的文件:

a|b|c|clm4=1|clm5=3
a|b|c|clm4=9|clm6=60|clm7=23

我想閱讀它並將其轉換為如下所示的數據幀:

clm1|clm2|clm3|clm4|clm5|clm6|clm7
a|b|c|1|3|null|null
a|b|c|9|null|60|23

我嘗試了以下方法:

files = [f for f in glob.glob(pathToFile + "/**/*.txt.gz", recursive=True)]
df = spark.read.load(files, format='csv', sep = '|', header=None)

但它給了我以下結果:

clm1, clm2, clm3, clm4, clm5
a, b, c, 1, 3
a, b, c, 9, null

對於 Spark 2.4+,您可以將文件作為單列讀取,然后按|拆分| . 您將獲得一個數組列,您可以使用高階函數對其進行轉換

df.show(truncate=False)

+----------------------------+
|clm                         |
+----------------------------+
|a|b|c|clm4=1|clm5=3         |
|a|b|c|clm4=9|clm6=60|clm7=23|
+----------------------------+

我們使用transform函數將我們從拆分clm列中獲得的字符串數組轉換為結構數組。 如果存在,每個結構都包含列名(檢查字符串是否包含= )或將其命名為clm + (i+1) ,其中i是其位置。

transform_expr = """
transform(split(clm, '[|]'), (x, i) -> 
                   struct(
                         IF(x like '%=%', substring_index(x, '=', 1), concat('clm', i+1)), 
                         substring_index(x, '=', -1)
                         )
        )
"""

現在使用map_from_entries將數組轉換為映射。 最后,分解地圖並旋轉以獲得您的列

df.select("clm", 
          explode(map_from_entries(expr(transform_expr))).alias("col_name", "col_value")
         ) \
  .groupby("clm").pivot('col_name').agg(first('col_value')) \
  .drop("clm") \
  .show(truncate=False)

給出:

+----+----+----+----+----+----+----+
|clm1|clm2|clm3|clm4|clm5|clm6|clm7|
+----+----+----+----+----+----+----+
|a   |b   |c   |9   |null|60  |23  |
|a   |b   |c   |1   |3   |null|null|
+----+----+----+----+----+----+----+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM