如何使用pyspark

时间:2018-11-19 09:09:33

标签: python regex apache-spark pyspark

源数据如下所示。第四条记录中的一个字段具有多行字符串。

i1|j1|k1|l1|m1
i2|j2|k2|l2|m2
i3|j3|k3|l3|m3
i4|j4|k4|"l4 is
multiline data
multiline data"|m4
i5|j5|k5|l5|m5

我正在通过sc.wholeTextFiles

读取此文件
rdd= sc.wholeTextFiles("file.csv").flatMap(lambda x: x[1].split("\n"))
print rdd.take(100)
print rdd.count()

rdd.take(100)的输出:

[u'i1|j1|k1|l1|m1', u'i2|j2|k2|l2|m2', u'i3|j3|k3|l3|m3', u'i4|j4|k4|"l4 is', u'multiline data', u'multiline data"|m4', u'i5|j5|k5|l5|m5', u'']

rdd.count()的输出

8

这里的问题是multiline数据被视为新记录。因此,计数也增加了。如何将multiline数据视为列的一个字符串值(以l4开头)?

1 个答案:

答案 0 :(得分:1)

一种方法是使用高级正则表达式表达式(仅受更新的regex模块支持)忽略双引号中的换行符:

"[^"]*"(*SKIP)(*FAIL)|\n

读为

"[^"]*"(*SKIP)(*FAIL) # match anything between double quotes and "forget" the match
|                     # or
\n                    # match a newline


Python中,应为:

import regex as re

data = """i1|j1|k1|l1|m1
i2|j2|k2|l2|m2
i3|j3|k3|l3|m3
i4|j4|k4|"l4 is
multiline data
multiline data"|m4
i5|j5|k5|l5|m5"""

rx = re.compile(r'"[^"]*"(*SKIP)(*FAIL)|\n')

lines = rx.split(data)
print(lines)

这会产生

['i1|j1|k1|l1|m1', 'i2|j2|k2|l2|m2', 'i3|j3|k3|l3|m3', 'i4|j4|k4|"l4 is\nmultiline data\nmultiline data"|m4', 'i5|j5|k5|l5|m5']

请注意,尽管转义的引号\")会破坏该机制。