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
我正在使用这个正则表达式: 我正在使用 pyspark 和 Jupyter 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:读取 pyspark 框架中的 csv 数据。为啥它在框架中显示特殊字符?除了使用熊猫之外,以表格形式显示的任何方式[重复]