如何使用PySpark删除RDD中的非可打印字符

3
需要从rdd中删除非可打印字符。
以下是示例数据。
"@TSX•","None"
"@MJU•","None"

预期输出
@TSX,None
@MJU,None

尝试了下面的代码,但它没有起作用。
sqlContext.read.option("sep", ","). \
                option("encoding", "ISO-8859-1"). \
                option("mode", "PERMISSIVE").csv(<path>).rdd.map(lambda s: s.replace("\xe2",""))
2个回答

1
你可以使用sparkContexttextFile函数,并使用string.printable从字符串中删除所有特殊字符
import string
sc.textFile(inputPath to csv file)\
    .map(lambda x: ','.join([''.join(e for e in y if e in string.printable).strip('\"') for y in x.split(',')]))\
    .saveAsTextFile(output path )

解释

对于您的输入行 "@TSX•","None"
for y in x.split(',') 将字符串行 分割成 ["@TSX•", "None"],其中 y 表示迭代时数组中的每个元素
for e in y if e in string.printable 检查 y 中的每个字符是否可打印
如果可打印,则这些字符将连接在一起形成可打印字符的字符串
.strip('\"') 从可打印字符串中删除前面和后面的引号
最后,通过','.join([''.join(e for e in y if e in string.printable).strip('\"') for y in x.split(',')])字符串列表转换为逗号分隔的字符串

我希望解释清楚易懂


代码可以运行,但我需要删除非可打印字符,而这些数据中需要特殊字符。有什么方法可以做到吗? - LUZO
1
我已经尽可能地解释了@LUZO。 - Ramesh Maharjan
你好@RameshMaharjan,你在Scala中有类似的方法吗?我已经花了一整天的时间去寻找它,但没有任何收获。谢谢。 - Kanav Sharma
@KanavSharma 在 Scala 中,你可以简单地执行 sc.textFile(input path ).map(_.split(",").map(x => x.replaceAll("^\"|\"$", "").replaceAll("[^\\x00-\\x7F]", "")).mkString(",")).saveAsTextFile(output path )。它的作用是将所有非 ASCII 字符替换为空,并替换开头和结尾的引号。希望这对你有所帮助,如果有帮助,请点赞。 - Ramesh Maharjan
@RameshMaharjan,谢谢。但是发生的情况是我的不想要的字符被Spark视为换行符。因此,一旦我通过创建RDD或数据帧使用Spark读取文件,它就会被replaceall函数省略掉。 - Kanav Sharma
显示剩余3条评论

1

一种选择是尝试使用string.printable过滤您的文本:

import string
sqlContext.read\
    .option("sep", ",")\
    .option("encoding", "ISO-8859-1")\
    .option("mode", "PERMISSIVE")\
    .csv(<path>)\
    .rdd\
    .map(lambda s: filter(lambda x: x in string.printable, s))

例子

import string
rdd = sc.parallelize(["TSX•,None","MJU•,None", "!@#ABC,*()XYZ"])

print(rdd.map(lambda s: filter(lambda x: x in string.printable, s)).collect())
#['TSX,None', 'MJU,None', '!@#ABC,*()XYZ']

参考资料


我不想删除特殊字符。有什么办法吗? - LUZO
@LUZO 这个解决方案不会移除特殊字符。string.printable包括所有可打印的字符。filter语句仅移除在string.printable中未找到的字符。请尝试并告诉我是否有效。 - pault
@LUZO,我已更新提供的示例,以表明此解决方案保留了特殊字符。 - pault
我已经尝试了你的代码。我遇到了以下错误:AttributeError: Can't pickle local object '<lambda>.<locals>.<lambda>'。 - LUZO
这似乎与不可打印字符问题无关。我怀疑你使用了更多的代码,但是没有分享。你能否编辑问题并添加完整的代码? - pault
我已经编辑了示例数据。我只想删除非可打印字符,所以我没有包含所有内容。 - LUZO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接