PySpark计算包含字符串的行

时间:2017-05-26 19:25:08

标签: python xml pyspark

我有多个看起来像这样的xml文件:

    <?xml version="1.0" encoding="UTF-8"?>
<parent>
  <row AcceptedAnswerId="15" AnswerCount="5" Body="&lt;p&gt;How should 
I elicit prior distributions from experts when fitting a Bayesian 
model?&lt;/p&gt;&#10;" CommentCount="1" CreationDate="2010-07-
19T19:12:12.510" FavoriteCount="17" Id="1" LastActivityDate="2010-09-
15T21:08:26.077" OwnerUserId="8" PostTypeId="1" Score="26" 
Tags="&lt;bayesian&gt;&lt;prior&gt;&lt;elicitation&gt;" 
Title="Eliciting priors from experts" ViewCount="1457" />

我希望能够使用PySpark来计算不包含字符串的行:<row

我目前的想法:

def startWithRow(line):
     if line.strip().startswith("<row"):
         return True
     else:
        return False

sc.textFile(localpath("folder_containing_xmg.gz_files")) \
    .filter(lambda x: not startWithRow(x)) \
    .count()

我已经尝试过验证这一点,但是即使是一个简单的计数行也没有意义的结果(我下载了xml文件,并在其上做了wc,它与PySpark中的字数不匹配。)

关于我的上述方法有什么突出的错误/怪异吗?

2 个答案:

答案 0 :(得分:0)

我将使用Scholarship库与Spark结合使用lxml计算行数或过滤掉某些内容。

row

例如,如果您有列表或XML字符串(只是玩具示例),则可以执行以下操作:

from lxml import etree

def find_number_of_rows(path):
    try:
        tree = etree.fromstring(path)
    except:
        tree = etree.parse(path)
    return len(tree.findall('row'))

rdd = spark.sparkContext.parallelize(paths) # paths is a list to all your paths
rdd.map(lambda x: find_number_of_rows(x)).collect()

在您的情况下,您的函数必须采用文件路径。然后,您可以计算或过滤这些行。我没有要测试的完整文件。如果您需要额外的帮助,请告诉我们!

答案 1 :(得分:0)

def badRowParser(x):    
    try:
        line = ET.fromstring(x.strip().encode('utf-8'))
        return True
    except:
        return False
posts = sc.textFile(localpath('folder_containing_xml.gz_files'))
rejected = posts.filter(lambda l: "<row" in l.encode('utf-
8')).map(lambda x: not badRowParser(x))
ans = rejected.collect()

from collections import Counter
Counter(ans)