【问题标题】:pyspark split csv with spaces in string - jupyter notebookpyspark 用字符串中的空格分割 csv - jupyter notebook
【发布时间】:2017-12-08 22:13:47
【问题描述】:

我不想读取文本文件,我想对现有数据框执行操作

我的DataFrame只有一列文本,就像一个文件,"tabSeparator"

这是一个结构化文件,有3列,分隔符是一个标签。 如果 有一个嵌入的 tab,它会用双引号括起来 ("xxx xx")

例子:

-------------------------
col_0
-------------------------
c11   c12    c13
c21 c22 c23   
"c 31" "c 32" c33

我正在使用这个正则表达式: 我正在使用 pysparkJupyter Notebook

myre = '([\\t ]?(\\".*?\\"|[^\\t ]+))'

df = textDF.withColumn("tmp", split( col("_c0"), myre))\
      .select(\
        col("tmp").getItem(0).alias("col_1"),\
        col("tmp").getItem(1).alias("col_2"),\
        col("tmp").getItem(2).alias("col_3")
      )

不确定问题出在正则表达式还是我解析文件的方式上,但我无法创建一个解析了 3 列的新 DataFrame,resulting on:

-------------------
|col_1|col_2|col_3|
------+-----+------
| c11 | c12 | c13 |
| c21 | c22 | c23 |  
| c 31| c 32| c 33|
-------------------

【问题讨论】:

    标签: python regex pyspark spark-dataframe


    【解决方案1】:

    这不是 csv 阅读器无法处理的:

    spark.read.option("delimiter", "\t").csv(path_to_file)
    

    在 Spark 2.3 中,您可以在现有的分布式数据结构上完成:

    df = spark.createDataFrame([
        'c11\tc12\tc13', 'c21\tc22\tc23', '"c\t31"\t"c\t32"\t"c\t33"'
    ], "string").toDF("col_0")
    
    
    spark.read.option('delimiter', '\t').csv(df.rdd.map(lambda x: x.col_0)).show()
    
    
    # +----+----+----+
    # | _c0| _c1| _c2|
    # +----+----+----+
    # | c11| c12| c13|
    # | c21| c22| c23|
    # |c    31|c    32|c    33|
    # +----+----+----+
    

    带有csv 的UDF 可能在带有Python 3 的2.2 中工作,但它会很慢:

    from pyspark.sql.functions import udf
    import csv
    
    @udf("struct<c0:string,c1:string,c2:string>")
    def csv_(s):
        try:
            return next(csv.reader([s], delimiter="\t"))
        except: pass
    
    df.select(csv_("col_0").alias("tmp")).select("tmp.*").show()
    
    # +----+----+----+
    # |  c0|  c1|  c2|
    # +----+----+----+
    # | c11| c12| c13|
    # | c21| c22| c23|
    # |c    31|c    32|c    33|
    # +----+----+----+
    

    【讨论】:

      【解决方案2】:

      显然你遇到的问题是有两个可能的分隔符。

      使用 DataFrames,加载只有一个分隔符的文件非常简单,例如制表符分隔符,它们被视为 CSV 文件,但不是逗号,它只是一个制表符。

      在这种特殊情况下,您会像这样阅读它们:

      yourDF = spark.read.option("delimiter", "\t").csv('/tabSeparator/')

      但如果你有多个,我相信唯一的选择是使用正则表达式。您也可以使用 RDD,编写更长的函数并使用 map。

      【讨论】:

      • 我已经有一个只有一列的数据框了!问题是如何解析它并创建 3 列。您可以假设制表符是唯一的分隔符。我不想按照您的建议阅读该文件,因为它不存在。
      • 感谢您的反对,只是想提供帮助 :) 如果您阅读了最后一部分,您会看到有一个选项可以使用 RDD 并按制表符进行简单的拆分,但您可以使用 SerDe引用。
      猜你喜欢
      • 2012-09-22
      • 2014-12-13
      • 2013-08-02
      • 2023-04-02
      • 2013-10-11
      • 1970-01-01
      • 1970-01-01
      • 2012-04-22
      • 2020-05-16
      相关资源
      最近更新 更多