我在清理数据方面遇到了一些问题,特别是数据缺失。
解析数据文件并进行初步数据清理后,数据快照如下:
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)