使用PySpark处理RDD中缺失的数据

时间:2017-02-21 21:05:49

标签: python pyspark rdd

我在清理数据方面遇到了一些问题,特别是数据缺失。

解析数据文件并进行初步数据清理后,数据快照如下:

r2.take(5)
Out[210]: 
[u'2016-10-26 13.43.06 C03 R27 80327 ONYX E 2605',
 u'2016-10-26 18.16.57 C04 R34 80544 GOLD E 7094',
 u'2016-10-26 18.24.15 C04 R33 80544 GOLD E 6875',
 u'2016-10-26 17.43.57 C03 R19 80908 ONYX E 5214',
 u'2016-10-26 17.07.55 C03 R27 80436 GOLD E 3436']

基于Spark教程,我执行以下后续步骤以[最终]创建Spark数据框架(我省略了一些步骤):

# Create RDD
from pyspark.sql import SQLContext, Row

# Load text files
parts = r2.map(lambda l: l.split(" "))
apachelogs = parts.map(lambda p: Row(
  date=p[0],
  time=p[1],
  category_code=p[2],
  item_code=p[3],
  purchase_ref=p[4],
  selling_team=p[5],
  language=p[6],
  gross_sales=p[7]))

经过几个步骤后,我尝试运行简单的命令,如.groupBy()。count()。collect()并遇到错误。当我回到我的数据时,我注意到我丢失了数据,特别是当我运行以下内容时:

parts.filter(lambda x: len(x) != 8).take(12)

Out[236]: 
[[u'2016-10-26', u'10.25.26', u'C04', u'800779', u'BLUE', u'E'],
 [u'2016-10-26', u'11.19.42', u'C03', u'803817', u'ONYX', u'E'],
 [u'2016-10-26', u'11.22.12', u'C04', u'8132705', u'GOLD', u'E'],
 [u'2016-10-26', u'11.22.22', u'C04', u'8154705', u'GOLD', u'E'],
 [u'2016-10-26', u'12.34.22', u'C05', u'8125781', u'ONYX', u'E'],
 [u'2016-10-26', u'12.40.05', u'C05', u'812381', u'ONYX', u'E'],
 [u'2016-10-26', u'22.16.42', u'C03', u'832347', u'ONYX', u'E'],
 [u'2016-10-26', u'18.07.36', u'C01', u'852300', u'GOLD', u'E'],
 [u'2016-10-26', u'11.26.39', u'C02', u'845424', u'BLUE', u'F'],
 [u'2016-10-26',
  u'12.16.00',
  u'C05',
  u'R39',
  u'845436668',
  u'BLUE',
  u'6975'],
 [u'2016-10-26', u'11.26.58', u'C05', u'83344280', u'GOLD', u'F']]

正如您所看到的,我们错过了以下列的观察结果:item_code,language和gross_sales。

我尝试做的是if else语句(或类似的东西)所以我可以修复这些列。我已在SQL环境中完成此代码,但不确定如何将其转换为PySpark环境。

例如,如果我们在SQL环境中工作,这是我在SQL中的代码:

select date, time, category_code, 
if(item_code like '8%','',item_code) as item_code,

/* Lets look at this code in the example below*/
if(item_code like '8%',item_code,if(purchase_ref not in ('GOLD','ONYX'),purchase_ref,'')) as purchase_ref,

if(purchase_ref in ('GOLD','ONYX'),purchase_ref,if(selling_team in ('GOLD','ONYX'),selling_team,'')) as selling_team,

if(selling_team in ('E','F'),selling_team,if(language in ('E','F'),language,'')) as language,

if(gross_sales is null,language,gross_sales) as gross_sales

让我们看一个例子。 purchase_ref始终以数字#34; 8"开头。对于purchase_ref列,如果item_code包含purchase_ref数字,原因是由于数据丢失而导致值被移位,则其结果应为该数字。如果它包含selling_team值,请将其留空。

当我尝试修复丢失数据的行时,SQL代码有效。

我的问题是: 如何从此问题中清除我的数据?

另外,如果我在Spark数据框中做到这一点会更加可行(我可以想象我将如何使用Pandas np.where来解决这个问题,但不确定如何在此处进行转换)?

感谢。

修改

为了更清楚我的初步步骤,它们如下:

从AWS导入文本文件。这是原始的:

myApacheLogs.take(25)
Out[227]: 
[u'  2016-10-26  13.43.06  C03    R27       84327  ONYX  E     2605                                        ',
 u'',
 u'  2016-10-26  18.16.57  C04    R34       896544  GOLD  E     7094                                        ',
 u'',
 u'  2016-10-26  18.24.15  C04    R33       867544  GOLD  E     6875                                        ',
 u'',
 u'  2016-10-26  17.43.57  C03    R19       8776908  ONYX  E     5214                                        ',
 u'',
 u'  2016-10-26  17.07.55  C03    R27       8654436  GOLD  E     3436                                        ']

我用以下方法做了一些清理:

r1 = myApacheLogs.filter(lambda x: x is not u'').filter(lambda x: x is not u'')
r1.take(10)
Out[209]: 
[u'  2016-10-26  13.43.06  C03    R27       84327  ONYX  E     2605                                        ',
 u'  2016-10-26  18.16.57  C04    R34       84544  GOLD  E     7094                                        ',
 u'  2016-10-26  18.24.15  C04    R33       84544  GOLD  E     6875                                        ',
 u'  2016-10-26  17.43.57  C03    R19       895408  ONYX  E     5214                                        ',
 u'  2016-10-26  17.07.55  C03    R27       86436  GOLD  E     3436                                        ',
 u'  2016-10-26  13.01.30  C05    R43       248945  GOLD  E     6956                                        ',
 u'  2016-10-26  10.07.10  C03    R29       863356  GOLD  E     0861                                        ',
 u'  2016-10-26  11.31.19  C04    R32       865684  ONYX  E     2595                                        ',
 u'  2016-10-26  13.31.33  C01    RR1       865690  ONYX  F     7093                                        ',
 u'  2016-10-26  14.06.37  C03    R20       865243  GOLD  E     6959                                        ']

def myFunc(s):
  results = re.sub("\s\s+" , " ", s) # Properly space columns
  results = results.lstrip() # Remove whitespace on the left
  results = results.rstrip() # Remove whitespace on the right
  return results
r2 = r1.map(myFunc)

0 个答案:

没有答案