pyspark 用字符串中的空格分割 csv - jupyter notebook

Posted

技术标签:

【中文标题】pyspark 用字符串中的空格分割 csv - jupyter notebook【英文标题】:pyspark split csv with spaces in string - 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|
-------------------

【问题讨论】:

【参考方案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引用。

以上是关于pyspark 用字符串中的空格分割 csv - jupyter notebook的主要内容,如果未能解决你的问题,请参考以下文章

使用 pyspark 处理 csv 文件中字段中的逗号

修改字符串列并替换子字符串 pyspark

在字符后用空格/两个空格分割字符串

pyspark用正则表达式读取csv文件

PySpark:读取 pyspark 框架中的 csv 数据。为啥它在框架中显示特殊字符?除了使用熊猫之外,以表格形式显示的任何方式[重复]

java编程:如何自行输入数字来用空格分割字符串?