无法使用PySpark应用架构 - 不一致的字段

时间:2016-07-19 15:16:14

标签: hadoop apache-spark pyspark

PySpark newb在这里,我试图组织一个笨拙的历史数据RDD。我从(来自WASB)读取数据并需要了解其结构。我对Schema有一个大概的想法,但因为这是一个很大的提取,我可以看到并非所有记录都是一致的。

我所挣扎的是按位置引用RDD元素,以便我可以尝试从数据中提取某些意义。由于不一致,我现在无法提交Schema - 这意味着数据帧不是一个选项,我失去了DF的灵活查询风格。

有关环境和数据的快速摘要:
Azure HDInsight Clusters,WASB中的数据
HDFS v.2.7
YARN v.2.7
Spark v 1.6(具有8个工作节点的HA配置(每个16 Core x 112 GB) Jupyter - PySpark
数据:奇怪的分隔" CSV"大约765MM记录

阅读数据
ops = sc.textFile("wasb://blob@storageaccount.windows.net/raw_ops.csv")

拆分时髦的分隔符
ops = ops.map(lambda s: s.split(u"\ufffd")).cache()

显示5条RDD记录
ops.take(5)

[ [u'ALER RECOMMENDED BRAKE FLUID EXCHANGE - $139.88 ~', u'~PERFORMED DEALER RECOMMENDED BRAKE FLUID EXCHANGE USING A SPECIAL BRAKE FLUID EXCHANGE MACHINE,A PRESSURIZED SUPPLY OF MOC BRAKE FLUID', u'HIST_LD', u'2016-03-08 16:02:53', u'ARCHIVE'] ,[u'04638', u'0734140', u'2011-10-19', u'345267460', u'2', u'TIR', u'', u'0', u'685745051', u'TIRE INFLATION RULE CK ALL TIRES FOR ACCURATE PSI PER MANUFACTURER SPECIFICATION', u'HIST_LD', u'2016-03-08 16:01:39', u'ARCHIVE'] ,[u'04638', u'0734140', u'2011-10-19', u'345267460', u'1', u'PRIME ITEM', u'', u'0', u'0', u'TIRE INFLATION RULE CK ALL TIRES FOR ACCURATE PSI PER MANUFACTURER SPECIFICATION ~', u'~TIRE INFLATION RULE CK ALL TIRES FOR ACCURATE PSI PER MANUFACTURER SPECIFICATIONS AND DOCUMENT PSI ~', u'~ ~', u'~20450 SET AT 36 PSI.', u'HIST_LD', u'2016-03-08 16:01:39', u'ARCHIVE'] ,[u'12093', u'0399468', u'2011-10-19', u'345268559', u'2', u'201', u'', u'1.5', u'0', u'REPLACED GAS CAP AND SANDED FILLER NECK', u'HIST_LD', u'2016-03-08 16:07:15', u'ARCHIVE'] ,[u'12093', u'0399468', u'2011-10-19', u'345268559', u'1', u'PRIME ITEM', u'', u'0', u'0', u'REPLACED GAS CAP AND SANDED FILLER NECK ~', u'~REPLACE GAS CAP AND SAND FILLER NECK', u'HIST_LD', u'2016-03-08 16:07:15', u'ARCHIVE'] ]

我看到第3列可能是日期,如何从RDD中的每一行中提取此值?
伪代码样本在此查找2013年数据):
ops.filter(lambda x[2]: year(x[2])==2013)

我发现有关如何在线执行此操作的有限文档 - 特别是因为它涉及在没有决定性架构的情况下纠缠不一致结构化数据。底线应该是"伪代码"实际上是?

我的最终目标是解析2013-2015的数据,将这些数据划分为自己的数据框并将其写入Hive。谢谢你的帮助!

2 个答案:

答案 0 :(得分:0)

所以这是解决问题的一种方法:

from datetime import datetime  

def only_pass(maybe_date):  
    try:  
        datetime.strptime(maybe_date,"%Y-%m-%d").date()  
        return 1  
    except Exception as err:    
        return 0   

only_rows_with_dates = rdd.filter(lambda row: only_pass(row[2]) == 1)  
  • 这里无法对齐:/希望你明白这一点。

答案 1 :(得分:0)

我认为目前的最佳选择是

  1. 根据分隔符
  2. 拆分RDD中的行

    rddNew = rddOriginal.map(lambda s: s.split(u"\ufffd")).cache()

    1. 使用“re”库中的RegEx技能搜索您怀疑是相关日期的元素,并为“分区”创建新的RDD
    2. import re rdd2013 = opcode.filter(lambda x : re.search('^2013', x[2]))